6

I know accessing the attributes of Foo through an instance will call the __getattribute__() method, but what if I access this attribute directly through the class? If a function is called, I want to set a breakpoint in it so that the breakpoint can be triggered when accessing this property through a class in my project.

I have tried to set breakpoint in magic method __getattribute__(), but nothing hapened.

class Foo:
    age = 18


print(Foo.age)  # I am curious what method is called
4
  • Interesting article Commented Jul 17, 2020 at 7:45
  • __dict__ isn't a method; the instance dict is directly available with this name, you don't call it. Commented Jul 17, 2020 at 8:31
  • 1
    @KarlKnechtel Technically __dict__ is a descriptor which provides the instance dict. Commented Jul 17, 2020 at 8:34
  • Thanks for your help, I mistakenly thought __dict__ is also a magic method. Commented Jul 17, 2020 at 10:32

1 Answer 1

5

Everything in Python is an object and everything has a type that determines the object's behavior. This also holds for class objects. You can check type(Foo):

>>> type(Foo)
<class 'type'>

You can customize the type of a class by providing a custom metaclass. This metaclass is then responsible for attribute access on the class object:

class MyMeta(type):
    def __getattribute__(self, name):
        print(f'__getattribute__({self!r}, {name!r})')
        return super().__getattribute__(name)


class Foo(metaclass=MyMeta):
    age = 18


print(Foo.age)

and the output is:

__getattribute__(<class '__main__.Foo'>, 'age')
18
Sign up to request clarification or add additional context in comments.

6 Comments

Without decoration, you would want to set the breakpoint in type.__getattribute__, but at least in the reference C implementation, type is implemented in C and there is nothing exposed where you could set such a breakpoint with pdb.
@KarlKnechtel You mean without using a custom metaclass? I'm not too familiar with the C API but I would be surprised if it exposed something to set a breakpoint in type.__getattribute__. Seems like a rare use case.
You would have to have a debug build of Python, compiled with the same IDE you're using to set the breakpoint, and with known compilation settings, I imagine.
In this case, could I override the __getattribute__ return in Foo? I tried the same structure as above, but changed to simply return 42 in MyMeta.__getattribute__. However if I call Foo.age I still get 18, not 42.
@tigerninjaman You mean you replaced return super().__getattribute__(name) with return 42? In that case Foo.age should return 42 and it works for me.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.