difference between __setattr__ and __dict__
Question:
if I want to set an attribute for a instance:
I can use __setattr__(key, value)
or self.__dict__[key]=value
I want to know how __setattr__
works, if __setattr__
just set the k,v in __dict__
, whats the differencet between two ways? What is the meaning of setattr’s existence?
Answers:
__setattr__(key, value)
is the function which gets called by setattr(instance, key, value)
.
__setattr__(key, value)
typically will act the same as self.__dict__[key]= value
unless the class the __setattr__
method in the function has been overridden in some way.
This might help docs
class MyClass(object):
def __setattr__(self, key, value):
print(f"setting {key}={value}")
if __name__ == "__main__":
m = MyClass()
m.a = 3
m.b = 6
m.__dict__.update({"c": 7})
print(f"{m.c=}")
print(f"{m.__dict__=}")
<script src="https://modularizer.github.io/pyprez/pyprez.min.js"></script>
while __dict__
is an internal dictionary that holds all of their internal variables, __setattr__
is actually a method that is always called when you try to set an attribute, and therefore, you can intercept these actions and act according.
A sample code can help you to understand the difference:
class Foo:
def __setattr__(self, key, value):
print(f'Setting {key} to {value}')
self.__dict__[key] = value
f = Foo()
f.__dict__['test'] = 1
f.__setattr__('test', 2)
f.test = 3
The output would be:
Setting test to 2
Setting test to 3
And the reason is that by accessing __dict__
, you are directly accessing the internal object dictionary and the __setattr__
method is skipped.
if I want to set an attribute for a instance:
I can use __setattr__(key, value)
or self.__dict__[key]=value
I want to know how __setattr__
works, if __setattr__
just set the k,v in __dict__
, whats the differencet between two ways? What is the meaning of setattr’s existence?
__setattr__(key, value)
is the function which gets called by setattr(instance, key, value)
.
__setattr__(key, value)
typically will act the same as self.__dict__[key]= value
unless the class the __setattr__
method in the function has been overridden in some way.
This might help docs
class MyClass(object):
def __setattr__(self, key, value):
print(f"setting {key}={value}")
if __name__ == "__main__":
m = MyClass()
m.a = 3
m.b = 6
m.__dict__.update({"c": 7})
print(f"{m.c=}")
print(f"{m.__dict__=}")
<script src="https://modularizer.github.io/pyprez/pyprez.min.js"></script>
while __dict__
is an internal dictionary that holds all of their internal variables, __setattr__
is actually a method that is always called when you try to set an attribute, and therefore, you can intercept these actions and act according.
A sample code can help you to understand the difference:
class Foo:
def __setattr__(self, key, value):
print(f'Setting {key} to {value}')
self.__dict__[key] = value
f = Foo()
f.__dict__['test'] = 1
f.__setattr__('test', 2)
f.test = 3
The output would be:
Setting test to 2
Setting test to 3
And the reason is that by accessing __dict__
, you are directly accessing the internal object dictionary and the __setattr__
method is skipped.