关于Python定制类中__getattr__的问题

这是在阅读廖雪峰老师的Python教程时遇到的问题
定制类


文章中提出来如何创建一个链式调用:

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'

对其原因的解释在评论区可以找到:

首先定义了Chain类,init函数接收一个path变量。
然后getattr函数,这个函数是如果你使用了类没有定义的变量的时候,就会调用它。它返回一个Chain(),并且把“原本的path/没有定义的变量”作为path的值传入了Chain里
call函数就是将类当作类似函数一样调用
str函数是当有打印函数是,就会调用这个
所以这段代码的执行流程为:
先是Chain()创建了一个实例,最开始的path默认为“”,然后.a,因为没有a这个变量,所以会调用getattr函数,返回一个Chain实例,然后把/a作为path传入,继续.b,因为没有b变量,所以执行getattr函数,将/a/b作为path传入,然后.user(“ChenTian”),先会执行getattr返回Chain实例,但是因为有()括号在,所以返回的是Chain(),这个就会调用call函数了,然后把“ChenTian”作为path传入,然后call函数就返回了/a/b/user/ChenTian,剩下的类同。
主要是user(“ChenTian”)这一句,我的理解是,先执行了getattr,然后执行call,并把ChenTian作为path传入
具体的细节我目前不是很清楚,我猜测是多了括号所以会调用call,不过不知道为什么。。。


按照这个说法,我做了一个实验:

class Chain(object):
    def __init__(self, path='initial'):
        self._path = path
    def __getattr__(self, path):
        return Chain('!%s@%s' %(self._path, path))
    def __str__(self):
        return self._path
    __repr__ = __str__

结果却是

from temp import Chain

Chain().status.user.timeline.list
Out[68]: !!!!initial@status@user@timeline@list

希望大神帮忙解答,为什么前面有连续的 ‘!’ 出现

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值