父类调用子类未绑定的方法

2016-06-12 17:26:23 +08:00
 sudo987
class Person(object):
    def __init__(self, height):
        self.height = height
    def show_height(self):
        return self.height

class Girl(Person):
    def __init__(self, height, breast):
        super(Man, self).__init__(height)
        self.breast = breast

p = Person(170)
Girl.show_height(p)

TypeError: unbound method show_height() must be called with Man instance as first argument (got Person instance instead)
错误很清晰,但是不太明白为什么不能这样调用,反过来却可以。

3840 次点击
所在节点    Python
20 条回复
sudo987
2016-06-12 17:33:53 +08:00
super 里的 Man 改成 Girl ,但这不是重点。
caoyue
2016-06-12 17:50:10 +08:00
我猜楼主是想通过 Girl.show_height(instance) 这样的方式去实现 Girl(170, 36).show_height() 的调用?

如果忽略那个 Man 的问题,也应该使用
p = Girl(170, 36)
Girl.show_height(p)
才对

因为 p 并不是 Girl 的 instance ,所以报错不是很正常么
JhZ7z587cYROBgVQ
2016-06-12 17:50:32 +08:00
show_height 应该是实例方法,你用 p 作为参数是不对的,然后因为 Girl 继承了 Person ,而你是按 classmethod 的方法在调用 show_height ,所以应该用 Girl 类的实例来调用这个方法
lujun9972
2016-06-12 18:25:10 +08:00
目测 LZ 用的 python2 ?用 python3 试试
mdzz
2016-06-12 18:28:18 +08:00
g = Girl(170)
g.show_height()

难道不是这样用?
tairan2006
2016-06-12 18:31:43 +08:00
你直接用`Girl`调用 method 是闹哪样…又不是 classmethod 或者 staticmethod
sudo987
2016-06-12 19:38:39 +08:00
@tairan2006 因为方法是类属性,不是实例属性,只是方法需要有实例和它绑定,所以 Girl.show_height(实例),这样调用没有问题。
iEverX
2016-06-12 19:52:49 +08:00
@sudo987 所以需要的是 Girl 的实例
sudo987
2016-06-12 19:56:28 +08:00
@iEverX 嗯,应该和 java 的多态一样( Girl 肯定是一个 Man ,但是 Man 不一定是一个 GIrl ),可我感觉 python 里的多态没啥用, python 不会做类型检查,是这样么?
tairan2006
2016-06-12 20:01:10 +08:00
@sudo987 没听说过这样用的,`self`这个参数就相当于其他语言的`this`,在使用`.`操作符的时候自动就传进去了。
你这里直接传一个实例进去,想手动指定 self ?这不符合语法吧。
iEverX
2016-06-12 20:02:17 +08:00
@sudo987 为啥没用? java 怎么用 python 就怎么用啊。
类型检查应该是没有,因为没有类型声明,不过这里是 method 不是 function ,应该是做了检查的
sudo987
2016-06-12 20:04:04 +08:00
@tairan2006 你可以试一下,没听说不代表不可以。
sudo987
2016-06-12 20:16:41 +08:00
@tairan2006
```
p = Person(1111) #实例化
p.show_height()#绑定,同时调用
我感觉 python 的这种“常规写法”是一种快捷方式,真正的方法调用就应该是
Person.show_height(p),因为方法是类属性不是实例属性,调用也应该是用“类.方法名”这样调用(因为方法的定义格式就是这样),然后传入实例进行方法绑定+调用,欢迎拍砖。

```
sudo987
2016-06-12 20:25:17 +08:00
@iEverX java 里是方法的参数比如说声明成父类,然后传入子类的实例,然后调用父类的方法,子类的实例覆盖父类的方法,于是调用父类的方法变成调用传入实例的方法, python 不做参数类型检查,只要是传入的实例有一样的方法名,就可以调用成功,那多态还有什么意义。。。不懂,求教。
tairan2006
2016-06-12 20:49:14 +08:00
@sudo987 我知道什么意思,但是你这研究的是 python 的实现…我觉得这就跟 C++里面的未定义行为一样,解释器到底怎么处理是不一定的,真要纠结这个问题就看 CPython 源码。
hst001
2016-06-12 23:12:07 +08:00
我没学过 python ,但是看你这逻辑就不对
lujun9972
2016-06-13 09:57:40 +08:00
@sudo987 Python3 才支持这种写法, Python2 不支持。
sudo987
2016-06-13 10:22:09 +08:00
@lujun9972 果然可以… Python 这么随意么…
mulog
2016-06-13 10:56:20 +08:00
If it looks like a duck, swims like a duck, and quacks like a duck, then it probably is a duck. :)
lujun9972
2016-06-13 11:56:50 +08:00
@sudo987 是的,当初发展 Python3 的时候就没想兼容 Python2

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/285162

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX