I experimented with the next code:
>>> f = object()
# It's obvious behavior:
>>> f.foo
Traceback (most recent call last):
File "", line 1, in
AttributeError: 'object' object has no attribute 'foo'
# However, the next one is surprising me!
>>> getattr(f, 'foo')
Traceback (most recent call last):
File "", line 1, in
AttributeError: 'object' object has no attribute 'foo'
# And this one returns None as expected:
>>> getattr(f, 'foo', None)
Then I found this pseudo-signature of getattr() in the PyCharm IDE:
def getattr(object, name, default=None): # known special case of getattr
"""
getattr(object, name[, default]) -> value
Get a named attribute from an object; getattr(x, 'y') is equivalent to x.y.
When a default argument is given, it is returned when the attribute doesn't
exist; without it, an exception is raised in that case.
"""
pass
My question is how does python distinguish this two scenarios of using getattr() (and maybe other functions) internally? And is it possible to do something similar entirely in the client side code?
解决方案
As @scytale said, the pseudo-signature of getattr doesn't quite correspond to its implementations. I've seen attempts to replicate the behaviour in pure Python that look something like this:
class MyObject(object):
__marker = object()
def getvalue(key, default=__marker):
...
if key is __marker:
# no value supplied for default
....
In other words, use a marker value that a caller cannot easily supply to check if no value was given as the default rather than None.