【问题标题】:Dynamically add properties to instances in Python [duplicate]在Python中为实例动态添加属性[重复]
【发布时间】:2012-05-18 22:14:05
【问题描述】:

我基本上对字典列表进行了精心包装:

class Wrapper(object):
    def __init__(self, data):
        self.data = data

    def get(self, attr):
        return [d[attr] for d in self.data]

所以,

Wrapper([{'x': 23}, {'x': 42}, {'x': 5}]).get('x')

返回[23, 42, 5]。现在我想分配速记属性,这样Wrapper.x 将返回与Wrapper.get('x') 相同的值。我不知道data 先验中存在哪些键,所以我目前的做法是(改编自this question

class Wrapper(object):
    def __init__(self, data):
        self.data = data
        for key in data[0].keys():
            setattr(self, key, property(lambda self: self.get(key)))

因此,假设数据的所有元素都具有相同的键,并且它们都是 python 中的有效标识符。但是,Wrapper(...).x 返回<property at 0x10a3d4838> 我做错了什么?

【问题讨论】:

  • @Martijn Pieters - 我认为您应该重新考虑如何在此处标记为重复。您链接到的文章是关于 classes 的,在 python 中这个特定主题与 instances 非常不同。
  • @JamieMarshall:不,OP 希望有基于实例中的值的动态属性。这并不排除在类中添加 __getattr__ 方法。另一篇文章涵盖了该选项。

标签: python dynamic properties


【解决方案1】:

您实际上可以通过更改函数名称轻松地做到这一点:

>>> class Wrapper(object):
...     def __init__(self, data):
...         self.data = data
...     def __getattr__(self, attr):
...         return [d[attr] for d in self.data]
... 
>>> Wrapper([{'x': 23}, {'x': 42}, {'x': 5}]).x
[23, 42, 5]

每当您请求不存在的属性时,都会调用 __getattr__() 特殊方法。这里唯一的潜在问题是您可以通过分配属性来覆盖它。如果您需要避免这种情况,只需覆盖 __setattr__() 即可阻止这种情况发生。

【讨论】:

  • 当然,我这边想太多的经典案例。
猜你喜欢
  • 1970-01-01
  • 2013-10-08
  • 2021-07-26
  • 2012-03-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-11
相关资源
最近更新 更多