views:

122

answers:

4

In Smalltalk there is a message DoesNotUnderstand that is called when an object does not understand a message (this is, when the object does not have the message sent implemented).

So, I like to know if in python there is a function that does the same thing.

In this example:

class MyObject:
    def __init__(self):
        print "MyObject created"

anObject = MyObject() # prints: MyObject created
anObject.DoSomething() # raise an Exception

So, can I add a method to MyObject so I can know when DoSomething is intented to be called?

PS: Sorry for my poor English.

+3  A: 

You are looking for the __getattr__ method. Have a look here.

If you want "total control" of a class, look at the __getattribute__ special method then (here).

jldupont
+3  A: 

Have you looked at object.__getattr__(self, name), or object.__getattribute__(self, name) for new-style classes? (see Special method names, Python language reference)

extraneon
+5  A: 

Here is a proposition for what you want to do:

class callee:
    def __init__(self, name):
        self.name = name

    def __call__(self):
        print self.name, "has been called"


class A:
    def __getattr__(self, attr):
        return callee(attr)

a = A()

a.DoSomething()
>>> DoSomething has been called
luc
This is defiantly what I want! Thanks :)
unkiwii
I like it when someone is definitely defiant! (or is that "defiantly definite"?) Whatever, SO saves the day again! :)
Paul McGuire
+1  A: 

I don't know why luc had the two separate classes. You can do it all with one class, if you use a closure. Like so:

class A(object):
    __ignored_attributes__ = set(["__str__"])

    def __getattr__(self, name):
        if __name__ in self.__ignored_attributes__:
            return None

        def fn():
            print name, "has been called with self =", self

        return fn

a = A()
a.DoSomething()

I added the bit about __ignored_attributes__ because Python was looking up __str__ in the class and that got a little messy.

Larry Hastings
two classes because it can be reused more easily. Imagine you want the same behavior for class B
luc