Zeck
Zeck

Reputation: 6579

Ruby’s “method_missing” in Python

Possible Duplicate:
Python equivalent of Ruby's 'method_missing'

Is there any technique available in Python for intercepting messages (method calls) like the method_missing technique in Ruby?

Upvotes: 18

Views: 12673

Answers (2)

Ned Batchelder
Ned Batchelder

Reputation: 375484

As others have mentioned, in Python, when you execute o.f(x), it's really a two-step operation: First, get the f attribute of o, then call it with parameter x. It's the first step that fails because there is no attribute f, and it's that step that invokes the Python magic method __getattr__.

So you have to implement __getattr__, and what it returns must be callable. Keep in mind, if you also try to get o.some_data_that_doesnt_exist, the same __getattr__ will be called, and it won't know that it's a "data" attribute vs. a "method" that being sought.

Here's an example of returning a callable:

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")

produces:

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

Upvotes: 49

pyroscope
pyroscope

Reputation: 4158

You can overload __getattr__ and return a callable from that. Note that you can NOT decide during attribute lookup whether the requested attribute is intended to be called, since Python does that in two steps.

Upvotes: 1

Related Questions