Python中的Ruby“method_missing”
在Python中有没有什么方法可以像Ruby的method_missing那样,拦截消息(方法调用)呢?
2 个回答
1
你可以重写 __getattr__
这个方法,并从中返回一个可以调用的东西。需要注意的是,在查找属性的时候,你不能决定请求的属性是否是想要被调用的,因为Python的处理是分两步进行的。
49
正如其他人提到的,在Python中,当你执行 o.f(x)
时,实际上是一个两步操作:第一步是获取 o
的 f
属性,然后用参数 x
调用它。出错的原因在于第一步,因为 o
没有 f
这个属性,这个步骤会触发Python的魔法方法 __getattr__
。
所以你需要实现 __getattr__
,而且它返回的内容必须是可以调用的。要记住的是,如果你尝试获取 o.some_data_that_doesnt_exist
,同样的 __getattr__
也会被调用,而它并不知道你是在寻找一个“数据”属性还是一个“方法”。
下面是一个返回可调用对象的例子:
class MyRubylikeThing(object):
#...
def __getattr__(self, name):
def _missing(*args, **kwargs):
print "A missing method was called."
print "The object was %r, the method was %r. " % (self, name)
print "It was called with %r and %r as arguments" % (args, kwargs)
return _missing
r = MyRubylikeThing()
r.hello("there", "world", also="bye")
产生的结果是:
A missing method was called.
The object was <__main__.MyRubylikeThing object at 0x01FA5940>, the method was 'hello'.
It was called with ('there', 'world') and {'also': 'bye'} as arguments