In Python, can you call an instance method of class A, but pass in an instance of class B?
为了重用一些定义为不同类的实例方法的现有代码,我打算执行如下操作:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | class Foo(object): def __init__(self): self.name ="Foo" def hello(self): print"Hello, I am" + self.name +"." class Bar(object): def __init__(self): self.name ="Bar" bar = Bar() Foo.hello(bar) |
但结果是:
TypeError: unbound method hello() must be called with Foo instance as first argument (got Bar instance instead)
号
这样的事情有可能吗?
我应该清楚我知道这是个坏主意。显然,真正的解决方案是重构。我只是想一定有办法,结果证明是有办法的。
谢谢你的评论。
看起来这是可行的:
1 | Foo.hello.im_func(bar) |
Hello, I am Bar.
号
我想我需要更努力地阅读…
发生这种情况是因为python将类函数包装为执行此类型检查的"未绑定方法"。这里有一些有关决定的描述。
注意,这种类型检查实际上已经在python 3中被删除了(参见文章末尾的注释),因此您的方法可以在这里工作。
这是一个古老的问题,但是python已经进化了,看起来值得指出:
对于python 3,没有更多的
这可能意味着不应该考虑原始问题中的代码。无论如何,python一直都是关于鸭子打字的,不是吗?!
参考文献:- guido建议从python中删除未绑定的方法
- Python3版本的新增功能
- 获取python 3中未绑定方法对象的定义类
PY2中的替代溶液
请注意,对于"探索性"问题,还有另一种解决方案(请参见python:bind an unbound method?):
1 2 3 4 5 6 7 | In [6]: a = A.a.im_func.__get__(B(), B) In [7]: a Out[7]: <bound method B.a of <__main__.B instance at 0x7f37d81a1ea8>> In [8]: a(2) 2 |
号
裁判:
一些ipython代码示例Python21 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | In [1]: class A(): def a(self, a=0): print a ...: In [2]: A.a Out[2]: <unbound method A.a> In [3]: A.a.im_func Out[3]: <function __main__.a> In [4]: A.a(B()) --------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-4-7694121f3429> in <module>() ----> 1 A.a(B()) TypeError: unbound method a() must be called with A instance as first argument (got B instance instead) |
Python3
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | In [2]: class A(): def a(self, a=0): print(a) ...: In [3]: def a(): ...: pass ...: In [4]: class B(): ...: pass In [5]: A.a(B()) 0 In [6]: A.a Out[6]: <function __main__.A.a> |
。
前一段时间,我对Perlmounds上Perl的相同"特性"感到好奇,大家普遍认为,当它工作时(就像在Python中一样),您不应该这样做。