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?
Python's magic method __setattr__() implements the built-in setattr() function that takes an object and an attribute name as arguments and removes the attribute from the object. We call this a “Dunder Method” for “Double Underscore Method” (also called “magic method”).
The setattr() function sets the value of the specified attribute of the specified object.
Python setattr() function is used to set a value to the object's attribute. It takes three arguments an object, a string, and an arbitrary value, and returns none. It is helpful when we want to add a new attribute to an object and set a value to it.
As we can see, dict() is obviously slower than {}. Especially, if the dictionary is initialized with many elements, it has a huge impact if your code needs 0.04ms or almost 0.08ms to create your dictionary. Even when you initialize an empty dictionary, it is slower.
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.
__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>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With