I am trying to understand when to use __getattr__
or __getattribute__
. The documentation mentions __getattribute__
applies to new-style classes. What are new-style classes?
相关问题
- how to define constructor for Python's new Nam
- streaming md5sum of contents of a large remote tar
- How to get the background from multiple images by
- Evil ctypes hack in python
- Correctly parse PDF paragraphs with Python
New-style classes inherit from
object
, or from another new style class:Old-style classes don't:
This only applies to Python 2 - in Python 3 all the above will create new-style classes.
See 9. Classes (Python tutorial), NewClassVsClassicClass and What is the difference between old style and new style classes in Python? for details.
Lets see some simple examples of both
__getattr__
and__getattribute__
magic methods.__getattr__
Python will call
__getattr__
method whenever you request an attribute that hasn't already been defined. In the following example my class Count has no__getattr__
method. Now in main when I try to access bothobj1.mymin
andobj1.mymax
attributes everything works fine. But when I try to accessobj1.mycurrent
attribute -- Python gives meAttributeError: 'Count' object has no attribute 'mycurrent'
Now my class Count has
__getattr__
method. Now when I try to accessobj1.mycurrent
attribute -- python returns me whatever I have implemented in my__getattr__
method. In my example whenever I try to call an attribute which doesn't exist, python creates that attribute and set it to integer value 0.__getattribute__
Now lets see the
__getattribute__
method. If you have__getattribute__
method in your class, python invokes this method for every attribute regardless whether it exists or not. So why we need__getattribute__
method? One good reason is that you can prevent access to attributes and make them more secure as shown in the following example.Whenever someone try to access my attributes that starts with substring 'cur' python raises
AttributeError
exception. Otherwise it returns that attribute.Important: In order to avoid infinite recursion in
__getattribute__
method, its implementation should always call the base class method with the same name to access any attributes it needs. For example:object.__getattribute__(self, name)
orsuper().__getattribute__(item)
and notself.__dict__[item]
IMPORTANT
If your class contain both getattr and getattribute magic methods then
__getattribute__
is called first. But if__getattribute__
raisesAttributeError
exception then the exception will be ignored and__getattr__
method will be invoked. See the following example:A key difference between
__getattr__
and__getattribute__
is that__getattr__
is only invoked if the attribute wasn't found the usual ways. It's good for implementing a fallback for missing attributes, and is probably the one of two you want.__getattribute__
is invoked before looking at the actual attributes on the object, and so can be tricky to implement correctly. You can end up in infinite recursions very easily.New-style classes derive from
object
, old-style classes are those in Python 2.x with no explicit base class. But the distinction between old-style and new-style classes is not the important one when choosing between__getattr__
and__getattribute__
.You almost certainly want
__getattr__
.This is just an example based on Ned Batchelder's explanation.
__getattr__
example:And if same example is used with
__getattribute__
You would get >>>RuntimeError: maximum recursion depth exceeded while calling a Python object
New-style classes are ones that subclass "object" (directly or indirectly). They have a
__new__
class method in addition to__init__
and have somewhat more rational low-level behavior.Usually, you'll want to override
__getattr__
(if you're overriding either), otherwise you'll have a hard time supporting "self.foo" syntax within your methods.Extra info: http://www.devx.com/opensource/Article/31482/0/page/4