【问题标题】:Python Object with @property's to dict带有 @property 的 Python 对象
【发布时间】:2015-04-01 14:24:14
【问题描述】:

我是 Python 新手,所以如果我对一些简单的操作感到困惑,请原谅。

我有一个这样的对象:

class myObject(object):
    def __init__(self):
        self.attr1 = None
        self.attr2 = None

    @property
    def prop1(self):
        return foo.some_func(self.attr1)

我这样实例化它:

a = myObject()
a.attr1 = 'Apple'
a.attr2 = 'Banana'

并且它所包含的方法期望返回dict,所以我这样做:

return a.__dict__

prop1 不包含在退货中。我明白这是为什么,它不在对象的__dict__ 中,因为它只包含真实属性。

所以问题是,我怎样才能让我的回报,回报是这样的:

{'attr1': 'Apple', 'attr2': 'Banana', 'prop1': 'ModifiedApple'}

除了在返回之前做的:

a.prop1_1 = a.prop1

【问题讨论】:

  • 为什么不在您的类中添加一个新方法,该方法返回带有属性值的self.__dict__ 的副本?
  • @MartijnPieters 这可能会解决这种特定情况,但不能解决查找任意对象属性值的一般情况。
  • @NickBailey:API 经常使用属性,因为检索值可能有点昂贵,并且计算值被推迟到您真正需要它时。如果您确实需要,您可以自动发现类上的所有 property 对象,但一般如果您不知道它们的用途,则戳所有属性不是一个好主意为。
  • 某些属性不会出现在实例的 __dict__ 中。该属性确实出现在类'__dict__ 中。看看这个stackoverflow.com/questions/14361256/…
  • @MartijnPieters。一个公平的观点。但是,如果您使用的是已知的类 API,那您为什么还要使用 dict

标签: python python-2.7 object dictionary


【解决方案1】:

您应该保留__dict__,仅将其用于直接存在于实例上的属性。

如果您需要生成包含属性名称和值的字典,您可以添加另一个生成新字典的属性或方法:

@property
def all_attributes(self):
    return dict(vars(self), prop1=self.prop1)

这可以通过自省自动检测所有属性对象,但请考虑到您使用属性以避免首先进行预先计算;触发所有属性的计算可能并不是那么理想。

【讨论】:

  • 巨大!我喜欢你的解决方案的清洁度!
  • 如果属性被@setter修改了怎么办?如果我有@property def uno(self): return self._uno@uno.setter def uno(self, val): self._uno = val*10 你的解决方案返回{'_uno': 100} 而不是{'uno': 100}
  • @leonardvertighel:它在实例属性映射中返回 all 键值对,是的。如果您明确添加它,它将返回uno,如果您不想显示_uno,则需要明确过滤掉它:return {**{k: v for k, v in vars(self) if k[:1] != '_'}, 'uno': self.uno} 过滤掉以下划线开头的键。
【解决方案2】:

你想要的是inspect 模块。

a = myObject()
a.attr1 = 'Apple'
a.attr2 = 'Banana'
inspect.getmembers(a)

返回

[('attr1','Apple'),('attr2','Banana'),('prop1','ModifiedApple')...]

请注意,getmembers 也会返回像 __sizeof__ 这样的内置成员,因此您可能需要对列表进行一些过滤。

如果你想把它当作字典,你可以随时使用

dict(inspect.getmembers(a))

【讨论】:

  • 过滤从inspect.getmembers返回的属性列表对于除了最简单的类之外的所有类都可能有点复杂,除非使用特定约定来命名您要查找的类属性(例如使用前缀'prop' 用于所有属性)...
猜你喜欢
  • 2010-11-23
  • 2014-05-30
  • 1970-01-01
  • 1970-01-01
  • 2017-07-13
  • 2016-05-30
  • 1970-01-01
  • 2014-10-22
  • 1970-01-01
相关资源
最近更新 更多