I was reading about the getattr()
function. The problem is that I still can't grasp the idea of its usage. The only thing I understand about getattr()
is that getattr(li, "pop")
is the same as calling li.pop
.
I didn't understand when the book mentioned how you use it to get a reference to a function without knowing its name until run-time. Maybe this is me being a noob in programming, in general. Could anyone shed some light to the subject? When and how do I use this exactly?
Quite frequently when I am creating an XML file from data stored in a class I would frequently receive errors if the attribute didn't exist or was of type
None
. In this case, my issue wasn't not knowing what the attribute name was, as stated in your question, but rather was data ever stored in that attribute.If I used
hasattr
to do this, it would returnTrue
even if the attribute value was of typeNone
and this would cause my ElementTreeset
command to fail.If the attribute value was of type
None
,getattr
would also return it which would cause my ElementTreeset
command to fail.I use the following method to take care of these cases now:
This is when and how I use
getattr
.A pretty common use case for
getattr
is mapping data to functions.For instance, in a web framework like Django or Pylons,
getattr
makes it straightforward to map a web request's URL to the function that's going to handle it. If you look under the hood of Pylons's routing, for instance, you'll see that (by default, at least) it chops up a request's URL, like:into "customers" and "list". Then it searches for a controller class named
CustomerController
. Assuming it finds the class, it creates an instance of the class and then usesgetattr
to get itslist
method. It then calls that method, passing it the request as an argument.Once you grasp this idea, it becomes really easy to extend the functionality of a web application: just add new methods to the controller classes, and then create links in your pages that use the appropriate URLs for those methods. All of this is made possible by
getattr
.Another use of getattr() in implementing a switch statement in Python. It uses both reflection to get the case type.
I sometimes use
getattr(..)
to lazily initialise attributes of secondary importance just before they are used in the code.Compare the following:
To this:
The advantage of the second way is that
n_calls_to_plot
only appears around the place in the code where it is used. This is good for readability, because (1) you can immediately see what value it starts with when reading how it's used, (2) it doesn't introduce a distraction into the__init__(..)
method, which ideally should be about the conceptual state of the class, rather than some utility counter that is only used by one of the function's methods for technical reasons, such as optimisation, and has nothing to do with the meaning of the object.Objects in Python can have attributes -- data attributes and functions to work with those (methods). Actually, every object has built-in attributes.
For example you have an object
person
, that has several attributes:name
,gender
, etc.You access these attributes (be it methods or data objects) usually writing:
person.name
,person.gender
,person.the_method()
, etc.But what if you don't know the attribute's name at the time you write the program? For example you have attribute's name stored in a variable called
attr_name
.if
then, instead of writing
you can write
Some practice:
getattr
will raiseAttributeError
if attribute with the given name does not exist in the object:But you can pass a default value as the third argument, which will be returned if such attribute does not exist:
You can use
getattr
along withdir
to iterate over all attribute names and get their values:A practical use for this would be to find all methods whose names start with
test
and call them.Similar to
getattr
there issetattr
which allows you to set an attribute of an object having its name: