视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
Python__setattr__、__getattr__、__delattr__、__call__用法示例
2020-11-27 14:31:45 责编:小采
文档


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

下载本文
显示全文
专题