Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

difference between __setattr__ and __dict__

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?

like image 908
Wynter Avatar asked Apr 21 '21 04:04

Wynter


People also ask

What is __ Setattr __ in python?

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”).

What does Setattr mean?

The setattr() function sets the value of the specified attribute of the specified object.

Why we use Setattr in python?

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.

What is the difference between dict and {}?

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.


2 Answers

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.

like image 175
rorra Avatar answered Oct 19 '22 15:10

rorra


__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>
like image 31
Modularizer Avatar answered Oct 19 '22 15:10

Modularizer