Ruby’s “method_missing” in Python [duplicate]
Asked Answered
D

2

18

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?

Deville answered 5/8, 2011 at 9:21 Comment(3)
Can you please describe the exact mechanism you're looking for?Gustavogustavus
I'm trying to implement something like Rails dynamic-finders in Python.Deville
@Zeck, I mean, can you please explain what are you looking for, for non-Ruby people?Gustavogustavus
U
49

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
Undeniable answered 5/8, 2011 at 11:53 Comment(1)
This could only cover the missing method. What if I want to cover missing member and method? "def __getattr__(self, name)", the name attribute is only a string, which is not enough to tell me if this atrribute with this name is a method, or a member.Champlin
E
1

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.

Epigone answered 5/8, 2011 at 9:30 Comment(1)
Thank you guys. I found a solution here. But I'm just wondering how to get passing parameters?Deville

© 2022 - 2024 — McMap. All rights reserved.