pythonsetattributegetattrgetattribute

Why isn't there __setattribute__ in python?


Python has these methods: __getattr__, __getattribute__, and __setattr__. I know the difference between __getattr__ and __getattribute__, this thread explains it well. But I couldn't find anywhere anybody mentioning why __setattribute__ doesn't exist.

Does somebody know the reasons for this? Thank you.


Solution

  • When getting an attribute, you can easily differentiate two cases: "this attribute exists in the normal path of attribute resolving" and "it can't be resolved via that path.". Therefore, there are two functions that can be plugged in: One that replaces the normal path (__getattribute__) and one that only handles the second case (__getattr__)

    In contrast, since you can in general [1] assign arbitrary attributes to objects, it is not possible to make the distinction between "this attribute can be assigned normally" and "this attribute needs special handling". Therefore for setting an arbitrary attribute it wouldn't really make sense to have two functions since their functionality would be confusing at best and inconsistent[2] at worst. So you only get one that fully replaces the normal path (__setattr__).


    [1] Usage of __slots__ and descriptors messes with this assumption. However, their usecases rarely overlap with the few situations where you would want to override attribute setting in general.

    [2] The question is "when does __setattribute__" call out to __setattr__?" If it fails to set the attribute? If the attribute does not exists right now? If __getattribute__ would call __getattr__ when getting the attribute?