The question refers to which one is preferable to be used in which use case, not about the technical background.
In python, you can control the access o
Basically, use the simplest one you can. Roughly speaking, the order of complexity/heavy-duty-ness goes: regular attribute, property
, __getattr__
, __getattribute__
/descriptor. (__getattribute__
and custom descriptors are both things you probably won't need to do very often.) This leads to some simple rules of thumb:
property
if a normal attribute will work.property
will work.__getattr__
if a property
will work.__getattribute__
if __getattr__
will work.Stated a bit more specifically: use a property to customize handling of one or a small set of attributes; use __getattr__
to customize handling of all attributes, or all except a small set; use __getattribute__
if you were hoping to use __getattr__
but it doesn't quite work; write your own descriptor class if you are doing something very complicated.
You use a property
when you have one or a small set of attributes whose getting/setting you want to hook into. That is, you want things like obj.prop
and obj.prop = 2
to secretly call a function that you write to customize what happens.
You would use __getattr__
when you want to do that for so many attributes that you don't actually want to define them all individually, but rather want to customize the whole attribute-access process as a whole. In other words, instead of hooking into obj.prop1
, and obj.prop2
, etc., you have so many that you want to be able to hook into obj.
, and handle that in general.
However, __getattr__
still won't let you override what happens for attributes that really do exist, it just lets you hook in with a blanket handling for any use of attributes that would otherwise raise an AttributeError. Using __getattribute__
lets you hook in to handle everything, even normal attributes that would have worked without messing with __getattribute__
. Because of this, using __getattribute__
has the potential to break fairly basic behavior, so you should only use it if you considered using __getattr__
and it wasn't enough. It also can have a noticeable performance impact. You might for instance need to use __getattribute__
if you're wrapping a class that defines some attributes, and you want to be able to wrap those attributes in a custom way, so that they work as usual in some situations but get custom behavior in other situations.
Finally, I would say writing your own descriptor is a fairly advanced task. property
is a descriptor, and for probably 95% of cases it's the only one you'll need. A good simple example of why you might write your own descriptor is given here: basically, you might do it if you would otherwise have to write several property
s with similar behavior; a descriptor lets you factor out the common behavior to avoid code repetition. Custom descriptors are used, for instance, to drive systems like like Django and SQLAlchemy. If you find yourself writing something at that level of complexity you might need to write a custom descriptor.
In your example, property
would be the best choice. It is usually (not always) a red flag if you're doing if name == 'somespecificname'
inside __getattribute__
. If you only need to specially handle one specific name, you can probably do it without stooping to the level of __getattribute__
. Likewise, it doesn't make sense to write your own descriptor if all you write for its __get__
is something you could have written in a property's getter method.