当前位置: 首页 > 编程笔记 >

Python __setattr__、 __getattr__、 __delattr__、__call__用法示例

曾皓
2023-03-14
本文向大家介绍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()

 类似资料:
  • 问题内容: 我知道调用类的实例时会触发类中的方法。但是,我不知道何时可以使用此特殊方法,因为一个人可以简单地创建一个新方法并执行在方法中完成的相同操作,而无需调用实例,而可以调用该方法。 如果有人给我这种特殊方法的实际用法,我将不胜感激。 问题答案: Django表单模块很好地使用了方法来实现用于表单验证的一致API。您可以将自己的表单验证程序编写为Django中的函数。 Django有一些默认的

  • 主要内容:用 __call__() 弥补 hasattr() 函数的短板本节再介绍 Python 类中一个非常特殊的实例方法,即 __call__()。该方法的功能类似于在类中重载 () 运算符,使得类实例对象可以像调用普通函数那样,以“对象名()”的形式使用。 举个例子: 程序执行结果为: 调用__call__()方法 小牛知识库 https://www.xnip.cn 可以看到,通过在 CLanguage 类中实现 __call__() 方法,使的 clangs

  • 问题内容: 我有一个包裹在另一个里面的物体。“包装器”通过重写从“包装”对象访问属性。直到我需要重写子类上的属性,然后使用来从基类访问该属性之前,此方法都有效。 我仍然可以直接从中访问属性,但是为什么不起作用? 问题答案: 据此, super不允许隐式调用诸如的“ hook”函数。我不确定为什么要用这种方式实现(这可能是一个很好的理由,并且由于超级对象具有自定义和方法,所以事情已经很混乱了),但似

  • 问题内容: 在讨论元类时,文档指出: 当然,您也可以覆盖其他类方法(或添加新方法)。例如,在元类中定义自定义方法可在调用类时允许自定义行为,例如,并非总是创建新实例。 我的问题是:假设我想在调用类时具有自定义行为,例如缓存而不是创建新对象。我可以通过重写类的方法来做到这一点。什么时候我想用它定义一个元类?这种方法带来了什么是无法实现的? 问题答案: 直接回答你的问题是:当你想要做 更多的 不仅仅是

  • 问题内容: 如何在模块上的类上实现等价于a的等价物? 例 当调用模块的静态定义属性中不存在的函数时,我希望在该模块中创建一个类的实例,并使用与该模块上的属性查找失败相同的名称调用该方法。 这使: 问题答案: 不久前,Guido宣布对新型类的所有特殊方法查找都绕过and。Dunder方法曾经工作的模块- 你可以,例如,使用一个模块作为一个上下文管理器简单地通过定义和,这些技巧之前爆发。 最近,一些历

  • 问题内容: 如何在模块上的类上实现等价于a 的等效项? 例 当调用模块的静态定义属性中不存在的函数时,我希望在该模块中创建一个类的实例,并使用与该模块上的属性查找失败相同的名称调用该方法。 这使: 问题答案: 你在这里遇到两个基本问题: 方法只在类上查找 (1)意味着任何解决方案还必须跟踪正在检查的模块,否则每个模块将具有实例替换行为;(2)表示(1)甚至是不可能的……至少不是直接的。 幸运的是,