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.
The getattr() function returns the value of the specified attribute from the specified object.
What is getattr() used for? Explanation: getattr(obj,name) is used to get the attribute of an object. 6.
__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.
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.
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 tox.foobar
. If the named attribute does not exist, default is returned if provided, otherwiseAttributeError
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). . .
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()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With