Discuss / Python / 对rest api动态实现这部分代码的理解

对rest api动态实现这部分代码的理解

Topic source
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__

url=Chain().status

print(type(url))
#输出<class '__main__.Chain'>

print(url)
#输出/status

print('maoge'+url)
#输出can only concatenate str (not "Chain") to str

首先对chain().status理解:创建一个chain类的实例(注意是没初始化属性_path的实例,你完全可以用s=chain();s.status取代这行代码),并调用chain属性status;

然后,由于chain类里面没有status属性,所以解释器就会检查类里面有没有创建__getattar__函数,我们这里创建了,所以开始调用__getatter__函数,此时执行 __getatter__(self,'status') (注意这里参数path接收到属性名status),返回 Chain('/status'),这时候我们得到了chain().status=chain('/status') ;我们发现结果依然是一个chain类的实例对象,并且这个实例的_path被初始化为'status';所以,chain().status.user=chain('status').user=chain('/status/user'),后面以此类推,不管点多少次,其实始终是返回一个chain实例,只是这个实例的_path属性越来越长了

至于后面print(chain().status) 为什么明明是一个对象却输出了/status字符串,这是因为chain类里面的__str__方法返回的是_path,所以我们每次输出chain类实例的对象就是输出该对象的_path


  • 1

Reply