我想使用new.instancemethod将函数(aFunction)从一个类(A)分配给另一个类(B)的实例.我不知道如何让aFunction允许自己应用于B的实例 - 目前我收到一个错误,因为aFunction期望在A的实例上执行.
[注意:我无法使用__class__属性将实例强制转换为A,因为我正在使用的类(在我的示例中为B)不支持类型转换]
import new
class A(object):
def aFunction(self):
pass
#Class which doesn't support typecasting
class B(object):
pass
b = B()
b.aFunction = new.instancemethod(A.aFunction, b, B.__class__)
b.aFunction()
Run Code Online (Sandbox Code Playgroud)
这是错误:
TypeError: unbound method aFunction() must be called with A instance as first argument (got B instance instead)
Run Code Online (Sandbox Code Playgroud)
new.instancemethod需要一个功能.A.aFunction是一种未绑定的方法.那不是一回事.(您可能想尝试加入一些打印语句来显示所有的东西involved- A.aFunction(),A().aFunction等和它们的类型,以帮助理解.)
我假设你没有描述符如何工作.如果你不想学习所有的血腥细节,那么实际发生的是你aFunction在类定义中的声明会从函数中创建一个非数据描述符.这是一个神奇的事情,这意味着,根据您访问它的方式,您将获得未绑定的方法(A.aFunction)或绑定方法(A().aFunction).
如果你修改aFunction为a @staticmethod,这实际上是有效的,因为对于静态方法而言A.aFunction,A().aFunction它们只是函数.(我不确定标准是否保证是真的,但是很难看出其他人会如何实现它.)但是如果你想要"aFunction允许自己应用于B的实例",那么静态方法不会帮助你.
如果你真的想要获得底层函数,有很多方法可以做到; 我认为这是帮助您理解描述符如何工作的最明确的:
f = object.__getattribute__(A, 'aFunction')
Run Code Online (Sandbox Code Playgroud)
另一方面,最简单的可能是:
f = A.aFunction.im_func
Run Code Online (Sandbox Code Playgroud)
然后,调用new.instancemethod是如何将该函数转换为可以作为B类实例的常规方法调用的描述符:
b.aFunction = new.instancemethod(f, b, B)
Run Code Online (Sandbox Code Playgroud)
打印出大量数据可以使事情变得更加清晰:
import new
class A(object):
def aFunction(self):
print self, type(self), type(A)
#Class which doesn't support typecasting
class B(object):
pass
print A.aFunction, type(A.aFunction)
print A().aFunction, type(A().aFunction)
print A.aFunction.im_func, type(A.aFunction.im_func)
print A().aFunction.im_func, type(A().aFunction.im_func)
A.aFunction(A())
A().aFunction()
f = object.__getattribute__(A, 'aFunction')
b = B()
b.aFunction = new.instancemethod(f, b, B)
b.aFunction()
Run Code Online (Sandbox Code Playgroud)
你会看到这样的事情:
<unbound method A.aFunction> <type 'instancemethod'>
<bound method A.aFunction of <__main__.A object at 0x108b82d10>> <type 'instancemethod'>
<function aFunction at 0x108b62a28> <type 'function'>
<function aFunction at 0x108b62a28> <type 'function'>
<__main__.A object at 0x108b82d10> <class '__main__.A'> <type 'type'>
<__main__.A object at 0x108b82d10> <class '__main__.A'> <type 'type'>
<__main__.B object at 0x108b82d10> <class '__main__.B'> <type 'type'>
Run Code Online (Sandbox Code Playgroud)
唯一没有显示的是创建绑定和未绑定方法的魔力.为此,你需要研究一下A.aFunction.im_func.__get__,在这一点上,你最好还是阅读描述符,而不是试图自己分开.
最后一件事:正如brandizzi指出的那样,这是你几乎不想做的事情.替代方案包括:写aFunction为自由函数而不是方法,所以你只需要调用b.aFunction(); 分解出,做实际工作的功能,并且有A.aFunction和B.aFunction叫它; 有B骨料的A并向其转交; 等等
| 归档时间: |
|
| 查看次数: |
1884 次 |
| 最近记录: |