当前位置 博文首页 > Python __setattr__、 __getattr__、 __delattr__、__call__用法

    Python __setattr__、 __getattr__、 __delattr__、__call__用法

    作者:admin 时间:2021-07-25 10:44

    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()

    jsjbwy