V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
sudo987
V2EX  ›  Python

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

  •  
  •   sudo987 · 2016-06-12 17:26:23 +08:00 · 3813 次点击
    这是一个创建于 3085 天前的主题,其中的信息可能已经有所发展或是发生改变。
    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)
    错误很清晰,但是不太明白为什么不能这样调用,反过来却可以。
    
    
    20 条回复    2016-06-13 11:56:50 +08:00
    sudo987
        1
    sudo987  
    OP
       2016-06-12 17:33:53 +08:00 via iPhone
    super 里的 Man 改成 Girl ,但这不是重点。
    caoyue
        2
    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
        3
    JhZ7z587cYROBgVQ  
       2016-06-12 17:50:32 +08:00
    show_height 应该是实例方法,你用 p 作为参数是不对的,然后因为 Girl 继承了 Person ,而你是按 classmethod 的方法在调用 show_height ,所以应该用 Girl 类的实例来调用这个方法
    lujun9972
        4
    lujun9972  
       2016-06-12 18:25:10 +08:00
    目测 LZ 用的 python2 ?用 python3 试试
    mdzz
        5
    mdzz  
       2016-06-12 18:28:18 +08:00
    g = Girl(170)
    g.show_height()

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

    ```
    sudo987
        14
    sudo987  
    OP
       2016-06-12 20:25:17 +08:00
    @iEverX java 里是方法的参数比如说声明成父类,然后传入子类的实例,然后调用父类的方法,子类的实例覆盖父类的方法,于是调用父类的方法变成调用传入实例的方法, python 不做参数类型检查,只要是传入的实例有一样的方法名,就可以调用成功,那多态还有什么意义。。。不懂,求教。
    tairan2006
        15
    tairan2006  
       2016-06-12 20:49:14 +08:00
    @sudo987 我知道什么意思,但是你这研究的是 python 的实现…我觉得这就跟 C++里面的未定义行为一样,解释器到底怎么处理是不一定的,真要纠结这个问题就看 CPython 源码。
    hst001
        16
    hst001  
       2016-06-12 23:12:07 +08:00
    我没学过 python ,但是看你这逻辑就不对
    lujun9972
        17
    lujun9972  
       2016-06-13 09:57:40 +08:00
    @sudo987 Python3 才支持这种写法, Python2 不支持。
    sudo987
        18
    sudo987  
    OP
       2016-06-13 10:22:09 +08:00 via iPhone
    @lujun9972 果然可以… Python 这么随意么…
    mulog
        19
    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
        20
    lujun9972  
       2016-06-13 11:56:50 +08:00
    @sudo987 是的,当初发展 Python3 的时候就没想兼容 Python2
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2744 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 30ms · UTC 12:02 · PVG 20:02 · LAX 04:02 · JFK 07:02
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.