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
xsaps
V2EX  ›  Python

Python新手问个调用成员函数的问题

  •  
  •   xsaps · 2013-01-02 18:37:39 +08:00 · 8220 次点击
    这是一个创建于 4345 天前的主题,其中的信息可能已经有所发展或是发生改变。
    在父函数中调用子函数的成员函数, 遇到个问题, 代码如下

    class Foo(object):
    def __init__(self):
    self._func = None

    def callDerivedFunc(self):
    # self._func() # wrong
    method = self._func
    method(self) # right

    class Bar(Foo):
    def __init__(self):
    super(Foo, self).__init__()
    self._func = Bar.hello

    def hello(self):
    print 'Hello'

    bar = Bar()
    bar.callDerivedFunc()

    一直以为这两种调用方法是一样的, 求教两者区别的详细解释
    7 条回复    1970-01-01 08:00:00 +08:00
    messense
        1
    messense  
       2013-01-02 18:52:18 +08:00
    直接调用 self._func() 的话,python 应该是优先查找 self 里面有没有 _func 这个方法,它发现没有,所以就出错了。
    messense
        2
    messense  
       2013-01-02 18:56:40 +08:00
    试试

    def callDerivedFunc(self):
    getattr(self, '_func')(self)
    xsaps
        3
    xsaps  
    OP
       2013-01-02 19:17:39 +08:00
    @messense 试了这样可以, 应该是和上面正确的调用形式一样
    yuelang85
        4
    yuelang85  
       2013-01-02 19:23:54 +08:00
    self._func = Bar.hello
    这一行将Bar类的hello函数赋值给self._func变量,而不是实例的hello函数,而hello函数是一个实例方法。

    method(self)调用没有错误,是因为给Bar.hello传递了一个实例,相当于:Bar.hello(bar)

    self._func()调用出错,是因为没有Bar.hello传递实例,相当于:Bar.hello()。所以会报错:"TypeError: unbound method hello() must be called with Bar instance as first argument (got nothing instead)"


    修改方法:

    def __init__(self):
    super(Foo, self).__init__()
    self._func = Bar.hello
    改成:
    def __init__(self):
    super(Foo, self).__init__()
    self._func = self.hello
    同时:
    method(self)
    改成:
    method()


    或者:

    self._func() # wrong
    改成:
    self._func(self) # wrong
    yuelang85
        5
    yuelang85  
       2013-01-02 19:31:20 +08:00
    用gist做了个好看版:D

    <script src="https://gist.github.com/4433964.js"></script>
    yuelang85
        6
    yuelang85  
       2013-01-02 19:38:22 +08:00
    上面那个失败了,重新学习了一下:

    http://gist.github.com/4433964
    xsaps
        7
    xsaps  
    OP
       2013-01-02 20:19:01 +08:00
    @yuelang85 thx, 是我混淆了直接调用成员函数和把成员变量当成函数调用的方法, 一开始还以为是self用法的问题...
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3128 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 14:05 · PVG 22:05 · LAX 06:05 · JFK 09:05
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.