gaussclb
gaussclb

Reputation: 1247

Does __dict__ exist or not in Python?

The first code snippet:

class A:
    def __init__(self):
        print(self.__dict__)
    def __getattr__(self, name):
        print("get")
    def __setattr__(self, name, value):
        print("set")

    # def __getattribute__(self, name):
    #     print("getatrr")

a = A()

It prints {} and the function __getattr__ isn't invoked, which means the attribute__dict__ exists.

The second snippet:

class A:
    def __init__(self):
        print(self.__dict__)
    def __getattr__(self, name):
        print("get")
    def __setattr__(self, name, value):
        print("set")

    def __getattribute__(self, name):
        print("getatrr")

a = A()

It prints getatrr and None, which means the attribute __dict__ doesn't exist.

Why is __dict__ {} in the first case, but None in the second case?

Upvotes: 0

Views: 823

Answers (1)

Jean-François Fabre
Jean-François Fabre

Reputation: 140186

the issue is that when you define this:

def __getattribute__(self, name):
    print("getatrr")

you're overriding __getattribute__ which is supposed to return something. Since you're not returning anything, you get None for every attribute you'll try.

Documentation states:

This method should return the (computed) attribute value or raise an AttributeError exception

A viable way to define it is to call object.__getattribute__ in the fallback case (in my example, I have added a small test on __dict__ which prints:

def __getattribute__(self, name):
    if name == "__dict__":
        print("get attribute invoked with __dict__")
    return object.__getattribute__(self,name)

In the end, the hard attribute lookup work is done with object.__getattribute__ that invokes python runtime.

Upvotes: 1

Related Questions