检查对象是否具有属性,而不依赖于“__getattr__”

2024-05-06

有没有一种方法可以检查对象是否具有不依赖于的属性__getattr__或对象实现细节?

考虑下面的代码。我想Proxy委托给Wrapped它无法处理什么。该代码有效,但我想避免测试attr in self.__dict__(我更喜欢一个稳定的接口来执行此操作,而不使用实现怪癖)。功能hasattr在这里没有帮助,因为它通过路由到包装对象__getattr__.

class Wrapped:
    def __init__(self):
        self.a = 0
        self.b = 1

class Proxy:
    def __init__(self, wrapped):
        object.__setattr__(self, 'wrapped', wrapped)
        object.__setattr__(self, 'a', 2)
    def __getattr__(self, attr):
        return getattr(self.wrapped, attr)
    def __setattr__(self, attr, value):
        if attr in self.__dict__:  # <-- Don't like this, hasattr doesn't work
            object.__setattr__(self, attr, value)
        elif hasattr(self.wrapped, attr):
            setattr(self.wrapped, attr, value)
        else: object.__setattr__(self, attr, value)

试驾:

>>> w = Wrapped()
>>> p = Proxy(w)
>>> p.a
2
>>> p.b
1
>>> p.a = 3
>>> p.a
3
>>> w.a
0
>>> p.b = 4
>>> p.b
4
>>> w.b
4
>>> p.c = 5
>>> p.c
5
>>> w.c
AttributeError: 'Wrapped' object has no attribute 'c'

内置的hasattr() https://docs.python.org/3/library/functions.html#hasattr功能

是通过调用实现的getattr(object, name)看看它是否会引发AttributeError or not.

The inspect https://docs.python.org/3/library/inspect.html模块有getattr_static() https://docs.python.org/3/library/inspect.html#inspect.getattr_static方法,可用于

通过描述符协议检索属性而不触发动态查找,__getattr__() or __getattribute__()".

使用此方法,您可以定义一个hasattr_static()方法类似于hasattr(),但是调用inspect.getattr_static(object, name)代替getattr(object, name):

import inspect


def hasattr_static(object, name):
    try:
        inspect.getattr_static(object, name)
        return True
    except AttributeError:
        return False

然后在__setattr__()你的方法Proxy类作为检查:

def __setattr__(self, attr, value):
    if hasattr_static(self, attr):
        object.__setattr__(self, attr, value)
    elif hasattr(self.wrapped, attr):
        setattr(self.wrapped, attr, value)
    else:
        object.__setattr__(self, attr, value)

或者,您可以使用dir() https://docs.python.org/3.5/library/functions.html#dir函数而不是__dict__检索对象的属性列表,或使用inspect.getmembers() https://docs.python.org/3/library/inspect.html#inspect.getmembers.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

检查对象是否具有属性,而不依赖于“__getattr__” 的相关文章

随机推荐