__str__
class Student(object): def __init__(self, name): self.name = name def __str__(self): return 'Student object (name: %s)' % self.name __repr__ = __str__ #Function
: Internal information can be printed directly
>>> print (Student( ' Michael ' )) Student object (name: Michael)
__getattr__
When calling an attribute that doesn't exist, for example score
, the Python interpreter will try to call __getattr__(self, 'score')
to try to get the attribute, so we have a chance to return score
the value:
class Student(object): def __init__(self): self.name = 'Michael' def __getattr__(self, attr): if attr=='score': return 99
>>> s = Student()
>>> s.name
'Michael'
>>> s.score
99
#It is also perfectly possible to return a function:
class Student(object): def __getattr__ (self, attr): if attr== ' age ' : return lambda : 25 The
call method should be changed to:
>>> s.age()
25
Any call s.abc
will return None
, this is because the __getattr__
default return we defined is None
. To make the class respond to only a few specific properties, we have to throw AttributeError
an error according to the convention:
class Student(object): def __getattr__(self, attr): if attr=='age': return lambda: 25 raise AttributeError('\'Student\' object has no attribute \'%s\'' % attr)
This can actually process all the properties and method calls of a class dynamically without any special means.
Example of action:
With fully dynamic __getattr__
, we can write a chained call:
class Chain(object): def __init__(self, path=''): self._path = path def __getattr__(self, path): return Chain('%s/%s' % (self._path, path)) def __str__(self): return self._path __repr__ = __str__
>>> Chain().status.user.timeline.list '
/status/user/timeline/list'
In this way, no matter how the API changes, the SDK can implement fully dynamic calls according to the URL, and it does not follow the API Increase and change!
Any class, just need to define a __call__()
method, you can directly call the instance.
class Student(object): def __init__(self, name): self.name = name def __call__ (self): print ( ' My name is %s. ' % self.name)
is called as follows:
>>> s = Student( 'Michael')
>>> s() # Do not pass
My name to the self parameter is Michael.