Chinaunix首页 | 论坛 | 博客
  • 博客访问: 4998716
  • 博文数量: 921
  • 博客积分: 16037
  • 博客等级: 上将
  • 技术积分: 8469
  • 用 户 组: 普通用户
  • 注册时间: 2006-04-05 02:08
文章分类

全部博文(921)

文章存档

2020年(1)

2019年(3)

2018年(3)

2017年(6)

2016年(47)

2015年(72)

2014年(25)

2013年(72)

2012年(125)

2011年(182)

2010年(42)

2009年(14)

2008年(85)

2007年(89)

2006年(155)

分类: Python/Ruby

2015-06-23 12:19:19

getattr

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

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

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

  1. #一个模块支持html、text、xml等格式的打印,根据传入的formate参数的不同,调用不同的函数实现几种格式的输出

  2. import statsout

  3. def output(data, format="text"):
  4.     output_function = getattr(statsout, "output_%s" %format)
  5.     return output_function(data)

__call__

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

  1. class storage(dict):
  2.     # __call__方法用于实例自身的调用
  3.     #达到()调用的效果
  4.     def __call__ (self, key):
  5.          try:
  6.              return self[key]
  7.          except KeyError, k:
  8.              return None

  9. s = storage()
  10. s['key'] = 'value'
  11. print s(key) #调用__call__

__getattr__

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


  1. class A(object):
  2.     def __init__(self):
  3.         self.name = 'from __dicts__: zdy'
  4.   
  5.     def __getattr__(self, item):
  6.         if item == 'name':
  7.             return 'from __getattr__: zdy'
  8.         elif item == 'age':
  9.             return 26
  10.   
  11. a = A()
  12. print a.name # 从__dict__里获得的
  13. print a.age # 从__getattr__获得的

__setattr__

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


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

__delattr__

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


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

例子

完整例子可以参考微博API:


  1. class _Executable(object):

  2.     def __init__(self, client, method, path):
  3.         self._client = client
  4.         self._method = method
  5.         self._path = path
  6.     #__call__函数实现_Executable函数对象为可调用的
  7.     def __call__(self, **kw):
  8.         method = _METHOD_MAP[self._method]
  9.         if method==_HTTP_POST and 'pic' in kw:
  10.             method = _HTTP_UPLOAD
  11.         return _http_call('%s%s.json' % (self._client.api_url, self._path), method, self._client.access_token, **kw)

  12.     def __str__(self):
  13.         return '_Executable (%s %s)' % (self._method, self._path)

  14.     __repr__ = __str__

  15. class _Callable(object):

  16.     def __init__(self, client, name):
  17.         self._client = client
  18.         self._name = name

  19.     def __getattr__(self, attr):
  20.         if attr=='get':
  21.        #初始化_Executable对象,调用__init__函数
  22.             return _Executable(self._client, 'GET', self._name)
  23.         if attr=='post':
  24.             return _Executable(self._client, 'POST', self._name)
  25.         name = '%s/%s' % (self._name, attr)
  26.         return _Callable(self._client, name)

  27.     def __str__(self):
  28.         return '_Callable (%s)' % self._name

  29.     __repr__ = __str__

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


  1. class APIClient(object):
  2.     '''
  3.     API client using synchronized invocation.
  4.     '''
  5.     ...

  6.     def __getattr__(self, attr):
  7.         if '__' in attr:
  8.             return getattr(self.get, attr)
  9.         return _Callable(self, attr)
因此,加入我们初始化对象,并调用某函数如下:

  1. client = APIClient(...)
  2. #会调用__getattr__函数,从而调用__call__函数
  3. client.something.get()


原文地址




阅读(1131) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~