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()
本文 由 cococo点点 创作,采用 知识共享 署名-非商业性使用-相同方式共享 3.0 中国大陆 许可协议进行许可。欢迎转载,请注明出处:
转载自:cococo点点 http://www.cnblogs.com/coder2012