Python中的Ruby“method_missing”

18 投票
2 回答
12300 浏览
提问于 2025-04-16 22:57

可能重复的问题:
Python中有没有类似Ruby的'method_missing'的方法?

在Python中有没有什么方法可以像Ruby的method_missing那样,拦截消息(方法调用)呢?

2 个回答

1

你可以重写 __getattr__ 这个方法,并从中返回一个可以调用的东西。需要注意的是,在查找属性的时候,你不能决定请求的属性是否是想要被调用的,因为Python的处理是分两步进行的。

49

正如其他人提到的,在Python中,当你执行 o.f(x) 时,实际上是一个两步操作:第一步是获取 of 属性,然后用参数 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

撰写回答