Python:在非类对象上调用方法的技巧
假设你定义了一个类,这个类里面有一个方法,做了一些复杂的处理:
class A(object):
def my_method(self):
# Some complicated processing is done here
return self
现在你想在另一个完全不同的类的对象上使用这个方法。比如,你想这样做:A.my_method(7)
。
但是你会遇到这个错误:TypeError: unbound method my_method() must be called with A instance as first argument (got int instance instead)
。意思是说,你必须用类A的实例来调用这个方法,而不是直接用数字7。
那么,有没有办法让你可以在7
上调用这个方法呢?我希望能避免移动这个函数或者重写它。(注意,这个方法的逻辑是依赖于self
的。)
有一点要说明:我知道有些人会想说,“你这样做不对!你在滥用Python!你不应该这么做!”所以是的,我知道,我想做的事情确实很糟糕。我只是想知道有没有人知道怎么做,而不是告诉我不应该这么做。
8 个回答
2
你是做不到的。这个限制在Python 3000中已经取消了,但我猜你并没有在用那个版本。
不过,为什么你不能像这样做呢:
def method_implementation(self, x,y):
# do whatever
class A():
def method(self, x, y):
return method_implementation(self, x, y)
如果你真的想挑战一下Python的极限,可以写一个描述符类来实现这个功能。大概像这样:
class Hack:
def __init__(self, fn):
self.fn = fn
def __get__(self, obj, cls):
if obj is None: # called staticly
return self.fn
else:
def inner(*args, **kwargs):
return self.fn(obj, *args, **kwargs)
return inner
请注意,这个代码完全没有经过测试,可能会在某些特殊情况下出问题,而且整体上来说并不太好。
2
def some_method(self):
# Some complicated processing is done here
return self
class A(object):
my_method = some_method
a = A()
print some_method
print a.my_method
print A.my_method
print A.my_method.im_func
print A.__dict__['my_method']
打印:
<function some_method at 0x719f0>
<bound method A.some_method of <__main__.A object at 0x757b0>>
<unbound method A.some_method>
<function some_method at 0x719f0>
<function some_method at 0x719f0>
听起来你是在查找一个类的方法,但得到的是一个 未绑定的方法
。一个 未绑定的方法
需要一个合适类型的对象作为第一个参数。
如果你想把这个函数当作普通函数来用,你需要找到它的函数版本。
6
当然,我不建议在真正的代码中这样做,但没错,你可以直接进入类里面,像用函数一样使用它的方法:
class A(object):
def my_method(self):
# Some complicated processing is done here
return 'Hi'
print(A.__dict__['my_method'](7))
# Hi