Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When is getattr() not like normal attribute access? [duplicate]

Tags:

python

Is there any difference between this code, which uses dot notation for attribute access:

def get_foo(self):
    try:
        return self._attribute
    except AttributeError:
        self._attribute = 'something'
        return self._attribute

And the following code, which uses the getattr function:

def get_foo(self):
    try:
        return getattr(self, '_attribute')
    except AttributeError:
        self._attribute = 'something'
        return self._attribute

They seem to behave the same way to me, but I came across the latter example in some code and I was curious why one would opt for calling getattr() in this case.

like image 817
larsks Avatar asked Dec 23 '15 20:12

larsks


People also ask

What is the Getattr () used for?

The getattr() function returns the value of the specified attribute from the specified object.

What is Getattr () used for * What is Getattr () used for to delete an attribute to check if an attribute exists or not to set an attribute?

What is getattr() used for? Explanation: getattr(obj,name) is used to get the attribute of an object. 6.

What does __ Getattr __ return?

__getattr__ __getattr__(self, name) Is an object method that is called if the object's properties are not found. This method should return the property value or throw AttributeError . Note that if the object property can be found through the normal mechanism, it will not be called.

What is Setattr () and Getattr () used for?

Python setattr() and getattr() goes hand-in-hand. As we have already seen what getattr() does; The setattr() function is used to assign a new value to an object/instance attribute.


2 Answers

According to the documentation, they are equivalent (unless a third argument is provided to suppress the AttributeError when the attribute is not present).

Return the value of the named attribute of object. name must be a string. If the string is the name of one of the object’s attributes, the result is the value of that attribute. For example, getattr(x, 'foobar') is equivalent to x.foobar. If the named attribute does not exist, default is returned if provided, otherwise AttributeError is raised.

I can't think of many reasons to prefer getattr over normal dot notation here . . . The only time I can think where I might be tempted to use the former is if I was trying to prevent my linter from complaining about protected-access (which is probably best disabled with a pragma if you have a legitimate reason for doing it). . .

like image 112
mgilson Avatar answered Oct 18 '22 08:10

mgilson


As the other answers provide, the two are functionally the same thing without the third argument.

One trivial difference is that they do not have the same effect on the stack; this is at best a code-golfy difference, and could only come up in very contrived scenarios (perhaps testing to see if you were in "debug" mode and providing different timings, if you were a malicious QA person).

import inspect

class Foo:

    def __init__(self):
        self._x = 3

    @property
    def x(self):
        curframe = inspect.currentframe()
        calframe = inspect.getouterframes(curframe, 2)      
        print(calframe[1][2])
        return self._x

f = Foo()
def bar():
    print( f.x )    
    # if instead we use the print statement on the next line,
    # we note that there is one more stack frame. In no universe
    # is this particularly impact, but in a closed test case
    # we would be able to determine which one was being used
    #print( getattr(f,'x') )

bar()
like image 43
en_Knight Avatar answered Oct 18 '22 07:10

en_Knight