Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I override class attribute access in python?

How can I override class attribute access in python?

P.S. Is there a way to leave regular access to class attributes alone but calling a more specific exception on missing attribute?

like image 706
Roman A. Taycher Avatar asked Mar 22 '12 10:03

Roman A. Taycher


2 Answers

The __getattr__ magic method is called when the attribute doesn't exist on the instance / class / parent classes. You'd use it to raise a special exception for a missing attribute:

class Foo:
    def __getattr__(self, attr):
        # only called when self.attr doesn't exist
        raise MyCustonException(attr)

If you want to customize access to class attributes, you need to define __getattr__ on the metaclass / type:

class BooType(type):
    def __getattr__(self, attr):
        print attr
        return attr

class Boo(metaclass=BooType):
    pass

boo = Boo()
Boo.asd # prints asd
boo.asd # raises an AttributeError like normal

If you want to customize all attribute access, use the __getattribute__ magic method.

like image 189
agf Avatar answered Sep 21 '22 12:09

agf


agf's answer is correct, and in fact the answer I'm about to give is based on it and owes it some credit.

Just to give more detail on the class-attribute side, which is the part that's actually under question here (as opposed to the difference between __getattr__ and __getattribute__), I'd like to add a reference to an answer I wrote to a different similar question, which goes into more detail on the difference between class and instance attributes, how this is implemented, and why you need to use a metaclass to influence class attribute lookup.

like image 24
metamatt Avatar answered Sep 21 '22 12:09

metamatt