zoukankan      html  css  js  c++  java
  • python __setattr__, __getattr__, __delattr__, __call__

    python __setattr__, __getattr__, __delattr__, __call__

     getattr

    `getattr`函数属于内建函数,可以通过函数名称获取

    value = obj.attribute
    value = getattr(obj, "attribute")

    使用`getattr`来实现工厂模式

    #一个模块支持html、text、xml等格式的打印,根据传入的formate参数的不同,调用不同的函数实现几种格式的输出
    
    import statsout 
    
    def output(data, format="text"):                           
        output_function = getattr(statsout, "output_%s" %format) 
        return output_function(data)

    __call__

    `__call__`方法用于实例自身的调用:

    class storage(dict):
        # __call__方法用于实例自身的调用
        #达到()调用的效果
        def __call__ (self, key):
             try:
                 return self[key]
             except KeyError, k:
                 return None
    
    s = storage()
    s['key'] = 'value'
    print s(key) #调用__call__

    __getattr__

    从对象中读取某个属性时,首先需要从self.__dicts__中搜索该属性,再从__getattr__中查找。

    class A(object):  
        def __init__(self):  
            self.name = 'from __dicts__: zdy'  
      
        def __getattr__(self, item):  
            if item == 'name':  
                return 'from __getattr__: zdy'  
            elif item == 'age':  
                return 26  
      
    a = A()  
    print a.name # 从__dict__里获得的  
    print a.age # 从__getattr__获得的  

    __setattr__

    `__setattr__`函数是用来设置对象的属性,通过object中的__setattr__函数来设置属性:

    class A(object):
        def __setattr__(self, *args, **kwargs):  
            print 'call func set attr'  
            return object.__setattr__(self, *args, **kwargs) 

    __delattr__

    `__delattr__`函数式用来删除对象的属性:

    class A(object):
        def __delattr__(self, *args, **kwargs):  
            print 'call func del attr'  
            return object.__delattr__(self, *args, **kwargs)  

    例子

    完整例子可以参考微博API:http://github.liaoxuefeng.com/sinaweibopy/

    class _Executable(object):
    
        def __init__(self, client, method, path):
            self._client = client
            self._method = method
            self._path = path
        #__call__函数实现_Executable函数对象为可调用的
        def __call__(self, **kw):
            method = _METHOD_MAP[self._method]
            if method==_HTTP_POST and 'pic' in kw:
                method = _HTTP_UPLOAD
            return _http_call('%s%s.json' % (self._client.api_url, self._path), method, self._client.access_token, **kw)
    
        def __str__(self):
            return '_Executable (%s %s)' % (self._method, self._path)
    
        __repr__ = __str__
    
    class _Callable(object):
    
        def __init__(self, client, name):
            self._client = client
            self._name = name
    
        def __getattr__(self, attr):
            if attr=='get':
           #初始化_Executable对象,调用__init__函数
    return _Executable(self._client, 'GET', self._name) if attr=='post': return _Executable(self._client, 'POST', self._name) name = '%s/%s' % (self._name, attr) return _Callable(self._client, name) def __str__(self): return '_Callable (%s)' % self._name __repr__ = __str__

    而在源码中,存在下面代码片段:

    class APIClient(object):
        '''
        API client using synchronized invocation.
        '''
        ... 
    
        def __getattr__(self, attr):
            if '__' in attr:
                return getattr(self.get, attr)
            return _Callable(self, attr)

    因此,加入我们初始化对象,并调用某函数如下:

    client = APIClient(...)
    #会调用__getattr__函数,从而调用__call__函数
    client.something.get()
  • 相关阅读:
    Python request
    Dockerfile详解
    k8s 英文文档翻译
    k8s 相关命令
    k8s 廖老师的分享
    Docker docker-compose安装
    Mysql 锁库与锁表
    Docker 二进制安装docker
    Java多线程的同步控制记录
    JAVA并行程序基础
  • 原文地址:https://www.cnblogs.com/coder2012/p/4309999.html
Copyright © 2011-2022 走看看