zoukankan      html  css  js  c++  java
  • Python对象里的 __call__ 和 __getattr__

    class Chain(object):
    
        def __init__(self, path=''):
            print("=", path)
            self._path = path
    
        def __getattr__(self, path):
    
            print(path, type(path))
            return Chain('%s/%s' % (self._path, path))
    
        def __call__(self, value):
            print('My name is %s.' % value)
            return Chain('%s/%s' % (self._path, ':' + value))
    
        def __str__(self):
            return self._path
    
        __repr__ = __str__
    
    
    # print(Chain().status.user.timeline.list)
    # 执行结果Chain().status = Chain('status')
    
    # GET /users/:user/repos
    # 调用时,需要把:user替换为实际用户名。如果我们能写出这样的链式调用:
    #
    print(Chain().users ('michael').repd)
    ('=', '')
    ('users', <type 'str'>)
    ('=', '/users')
    My name is michael.
    ('=', '/users/:michael')
    ('repd', <type 'str'>)
    ('=', '/users/:michael/repd')
    /users/:michael/repd
    

    定义__call__会再函数调用的时候执行。 getattr 会再调用实例某个不存在的属性是执行。

    Step 1:
    Chain()  # 实例化
    Step 2:
    Chain().users
    # 由于没有给实例传入初始化对应属性的具体信息,从而自动调用__getattr__()函数,从而有:
    Chain().users = Chain('users') # 这是重建实例
    Step 3:
    Chain().users('michael')
    Chain().users('michael') = Chain('users')('michael') # 这是对实例直接调用,相当于调用普通函数一样
    # 关键就在这步,上面的朋友没有说明晰(并不是说你们不懂),这一步返回的是Chain('usersmichael'),再一次重建实例,覆盖掉Chain('users'),
    #记 renew = Chain('usersmichael'), 此时新实例的属性renew.__path = usersmichael;
    Step 4:
    Chain().users('michael').repos
    # 这一步是查询renew实例的属性repos,由于没有这一属性,就会执行__getattr__()函数,再一次返回新的实例Chain('usersmichael
    epos')并且覆盖点之前的实例,
    # 这里记 trinew =Chain('usersmichael
    epos'),不要忘了,一单定义了一个新的实例,就会执行__init__方法;
    Step 5:
    print(Chain().users('michael').repos) = print(trinew)  #由于我们定义了__str__()方法,那么打印的时候就会调用此方法,据此方法的定义,打印回来的是trinew的__path属#性,即——usersmichael
    epos  。至此,我们也把所有定义的有特殊用的方法都用上了,完毕。
    廖雪峰教程下某个优秀的解释
    
  • 相关阅读:
    bug的约束
    bug管理规范
    FTP小教程
    测试需求,产品需求,项目需求
    如何理解客户需求、市场需求、产品需求、业务需求、特性、功能需求 ?(转)
    什么是测试需求?(转)
    绑定与非绑定,反射,内置方法
    面向对象之组合、封装、多态、property装饰器
    面向对象之继承与派生,属性查找
    面向对象基础
  • 原文地址:https://www.cnblogs.com/dg-blog/p/12718937.html
Copyright © 2011-2022 走看看