You cannot tell how an object is going to used in the __getattr__
hook, at all. You can access methods without calling them, store them in a variable, and later call them, for example.
Return an object with a __call__
method, it'll be invoked when called:
class CallableValue(object):
def __init__(self, name):
self.name = name
def __call__(self, *args, **kwargs):
print "Lo, {} was called!".format(self.name)
class Bar(object):
def __getattr__(self, name):
return CallableValue(name)
but instances of this will not be the same thing as a string or a list at the same time.
Demo:
>>> class CallableValue(object):
... def __init__(self, name):
... self.name = name
... def __call__(self, *args, **kwargs):
... print "Lo, {} was called!".format(self.name)
...
>>> class Bar(object):
... def __getattr__(self, name):
... return CallableValue(name)
...
>>> b = Bar()
>>> something = b.test_method
>>> something
<__main__.CallableValue object at 0x10ac3c290>
>>> something()
Lo, test_method was called!
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…