python __setattr__, __getattr__, __delattr__, __call__

getattr

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

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

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

  1. #一个模块支持html、text、xml等格式的打印,根据传入的formate参数的不同,调用不同的函数实现几种格式的输出
  2.  
  3. import statsout
  4.  
  5. def output(data, format="text"):
  6. output_function = getattr(statsout, "output_%s" %format)
  7. 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.  
  10. s = storage()
  11. s['key'] = 'value'
  12. 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:http://github.liaoxuefeng.com/sinaweibopy/

  1. class _Executable(object):
  2.  
  3. def __init__(self, client, method, path):
  4. self._client = client
  5. self._method = method
  6. self._path = path
  7. #__call__函数实现_Executable函数对象为可调用的
  8. def __call__(self, **kw):
  9. method = _METHOD_MAP[self._method]
  10. if method==_HTTP_POST and 'pic' in kw:
  11. method = _HTTP_UPLOAD
  12. return _http_call('%s%s.json' % (self._client.api_url, self._path), method, self._client.access_token, **kw)
  13.  
  14. def __str__(self):
  15. return '_Executable (%s %s)' % (self._method, self._path)
  16.  
  17. __repr__ = __str__
  18.  
  19. class _Callable(object):
  20.  
  21. def __init__(self, client, name):
  22. self._client = client
  23. self._name = name
  24.  
  25. def __getattr__(self, attr):
  26. if attr=='get':
           #初始化_Executable对象,调用__init__函数
  27. return _Executable(self._client, 'GET', self._name)
  28. if attr=='post':
  29. return _Executable(self._client, 'POST', self._name)
  30. name = '%s/%s' % (self._name, attr)
  31. return _Callable(self._client, name)
  32.  
  33. def __str__(self):
  34. return '_Callable (%s)' % self._name
  35.  
  36. __repr__ = __str__

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

  1. class APIClient(object):
  2. '''
  3. API client using synchronized invocation.
  4. '''
  5. ...
  6.  
  7. def __getattr__(self, attr):
  8. if '__' in attr:
  9. return getattr(self.get, attr)
  10. return _Callable(self, attr)

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

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

python __setattr__, __getattr__, __delattr__, __call__的更多相关文章

  1. python 中__setattr__, __getattr__,__getattribute__, __call__使用方法

    object._getattr_(self, name) 拦截点号运算.当对未定义的属性名称和实例进行点号运算时,就会用属性名作为字符串调用这个方法.如果继承树可以找到该属性,则不调用此方法 实例in ...

  2. __setattr__,__getattr__,__delattr__

    class Foo: x = 1 def __init__(self,y): self.y = y def __getattr__(self,item): print("---->fr ...

  3. __getattr__ __delattr__ __setattr__ __getattribute__使用(重写python提供的错误信息)

    自己定义了这些attr 查找删除设置就会触发自己定义的逻辑,如果不重新,pyton会提供自己报错信息class Room: def __init__(self,name): self.name = n ...

  4. python中的__getattr__、__getattribute__、__setattr__、__delattr__、__dir__

    __getattr__:     属性查找失败后,解释器会调用 __getattr__ 方法. class TmpTest: def __init__(self): self.tmp = 'tmp12 ...

  5. python面对对象编程-------5:获取属性的四种办法:@property, __setattr__(__getattr__) ,descriptor

    一:最基本的属性操作 class Generic: pass g= Generic() >>> g.attribute= "value" #创建属性并赋值 > ...

  6. 类的专有方法(__getattr__和__setattr__、__delattr__)

    # -*- coding: utf-8 -*- #python 27 #xiaodeng #http://www.360doc.com/content/15/0413/19/12067640_4629 ...

  7. python类内部方法__setattr__ __getattr_ __delattr__ hasattr __getattribute__ __getitem__(),__setitem__(), __delitem__()

    主要讲类的内部方法 __setattr__  __getattr_  __delattr__  hasattr  __getattribute__  __getitem__(),__setitem__ ...

  8. 第8.33节 Python中__getattr__以及__getattr__与__ getattribute__的关系深入剖析

    一. 引言 前面几节分别介绍了Python中属性操作捕获的三剑客:__ getattribute__方法.__setattr__方法.__delattr__方法,为什么__ getattribute_ ...

  9. python之 __getattr__、__getattr__、__getitem__、__setitem__ 使用

    python之 __getattr__.__getattr__.__getitem__.__setitem__ 使用 __getattr__内置使用点号获取实例属性属性如 s.name,自调用__ge ...

随机推荐

  1. C++之jsoncpp学习

    最新由于客户端要用到jsoncpp,所以自己也跟着项目的需求学了一下jsoncpp.以前没用过xml,但是感觉接触json后,还蛮好用的. 参考地址 http://jsoncpp.sourceforg ...

  2. 如何获得 request, "request.getSession(true).setAttribute("a",a);"与“request.setAttribute("a",a);”区别

    protected ServletContext getServletContext() { return ServletActionContext.getServletContext();} pro ...

  3. Android Studio鼠标悬停显示注释

    Android Studio鼠标悬停显示注释 在AS中配置 如果你想从网上查看注释,到这一步就操作完成. 下面说明让软件使用本地注释: 使用本地注释 以Windows为例: 找到下面文件 C:\Use ...

  4. oracle 同时更新(update)多个字段多个值

    --创建表A,B: create table A (a1 varchar2(33),a2 varchar2(33),a3 varchar2(33)); create table B (b1 varch ...

  5. wpf:样式(转)

    http://www.cnblogs.com/shuang121/archive/2013/01/14/2860455.html 前面简单的说到了wpf中几种样式的用法,wpf有着类似web中的CSS ...

  6. oracle 驱动安装备忘

    ubuntu 从oracle官网下载两个必须的rpm包(这里选择的是version12.1.0.2.0, 64位操作系统) oracle-instantclient12.1-basic-12.1.0. ...

  7. linux上安装jdk并添加环境变量

    ==========ubuntu============================= http://www.oracle.com/technetwork/java/javasebusiness/ ...

  8. JSON代码小计

    //strut json配置 <package name="mall_theme_ajax" extends="json-default" namespa ...

  9. 传统MySQL+ Memcached架构遇到的问题

    实际MySQL是适合进行海量数据存储的,通过Memcached将热点数据加载到cache,加速访问,很多公司都曾经使用过这样的架构,但随着业务数据量的不断增加,和访问量的持续增长,我们遇到了很多问题: ...

  10. 生成树的个数——基尔霍夫定理(Matrix-Tree Theorem)

    树有很多种形态,给定结点个数,求生成不同形态二叉树的个数,显然要用到Catalan数列. 那如果给定一个图(Graph)\(G=(V,E)\),要求其最小生成树G',最好的方法莫过于Prim或Krus ...