Python新手问个调用成员函数的问题 - V2EX
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 8635 次点击
    这是一个创建于 4675 天前的主题,其中的信息可能已经有所发展或是发生改变。
    在父函数中调用子函数的成员函数, 遇到个问题, 代码如下

    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     Solana     5448 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 31ms UTC 07:13 PVG 15:13 LAX 00:13 JFK 03:13
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86