gpt4 book ai didi

python 使用 __dict__ 获取对象属性

转载 作者:太空宇宙 更新时间:2023-11-04 07:56:50 25 4
gpt4 key购买 nike

使用 py3,我有一个使用 @property 装饰器的对象

class O(object):
def __init__(self):
self._a = None

@property
def a(self):
return 1

通过 __dict__(使用 _a)访问属性 a 似乎不会返回属性修饰值,而是返回初始化值 None

o = O()
print(o.a, o.__dict__['_a'])
>>> 1, None

是否有一种通用的方法来完成这项工作?我主要需要这个

def __str__(self):
return ' '.join('{}: {}'.format(key, val) for key, val in self.__dict__.items())

最佳答案

当然 self.__dict__["_a"] 将返回 self._a(实际上它是相反的 - self._a 将返回 self.__dict__["_a"] - 但无论如何),而不是 self.aproperty 在这里做的唯一一件事就是自动调用它的 getter(你的 a(self) 函数)所以你不必输入括号,否则它只是一个普通的方法调用。

如果你也想要一些与属性一起工作的东西,你必须手动从 dir(self.__class__)getattr(self.__class__, name),即:

def __str__(self):
# py2
attribs = self.__dict__.items()
# py3
# attribs = list(self.__dict__.items())

for name in dir(self.__class__):
obj = getattr(self.__class__, name)
if isinstance(obj, property):
val = obj.__get__(self, self.__class__)
attribs.append((name, val))

return ' '.join('{}: {}'.format(key, val) for key, val in attribs)

请注意,这不会阻止 _a 出现在 attribs 中 - 如果您想避免这种情况,您还必须从 中过滤掉 protected 名称>attribs 列表(所有 protected 名称,因为您要求的是通用名称):

def __str__(self):
attribs = [(k, v) for k, v in self.__dict__.items() if not k.startswith("_")]

for name in dir(self.__class__):
# a protected property is somewhat uncommon but
# let's stay consistent with plain attribs
if name.startswith("_"):
continue
obj = getattr(self.__class__, name)
if isinstance(obj, property):
val = obj.__get__(self, self.__class__)
attribs.append((name, val))

return ' '.join('{}: {}'.format(key, val) for key, val in attribs)

另请注意,这不会处理其他计算属性(property 只是描述符协议(protocol)的一种通用实现)。在这一点上,对于仍然尽可能通用但可以根据需要进行自定义的东西,最好的选择是将上面的内容实现为带有几个用于特化的钩子(Hook)的混合类:

class PropStrMixin(object):

# add other descriptor types you want to include in the
# attribs list
_COMPUTED_ATTRIBUTES_CLASSES = [property,]

def _get_attr_list(self):
attribs = [(k, v) for k, v in self.__dict__.items() if not k.startswith("_")]

for name in dir(self.__class__):
# a protected property is somewhat uncommon but
# let's stay consistent with plain attribs
if name.startswith("_"):
continue
obj = getattr(self.__class__, name)
if isinstance(obj, *self._COMPUTED_ATTRIBUTES_CLASSES):
val = obj.__get__(self, self.__class__)
attribs.append((name, val))
return attribs

def __str__(self):
attribs = self._get_attr_list()
return ' '.join('{}: {}'.format(key, val) for key, val in attribs)


class YouClass(SomeParent, PropStrMixin):
# here you can add to _COMPUTED_ATTRIBUTES_CLASSES
_COMPUTED_ATTRIBUTES_CLASSES = PropStrMixin + [SomeCustomDescriptor])

关于python 使用 __dict__ 获取对象属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47432613/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com