【问题标题】:Get dictionary that includes computed properties from Python object?获取包含来自 Python 对象的计算属性的字典?
【发布时间】:2017-05-17 22:39:35
【问题描述】:

假设我有一个 Python 类,其中包含在构造函数中创建的属性和使用 property 装饰器创建的计算属性的混合:

class Example:

    def __init__(self):
        self.foo = 1

    @property
    def bar(self):
        return 2

    def baz(self, x):
        return x * x

我想生成一个包含这两种属性的字典,但没有别的。但是,如果我这样做vars(Example()),我只会得到foo。如果我这样做dir(Example()),我会同时得到foobar,但也会得到baz 和大量其他垃圾。

是否可以自动生成这样的字典?我想我必须覆盖__dict__?也许通过调用dir 并以某种方式过滤掉不感兴趣的部分?

我想避免手动枚举所有属性。

【问题讨论】:

  • foo 是一个属性,而不是一个属性。
  • 不确定是否足够,但所有“垃圾”都以 __ 开头,为什么不过滤呢? [i for i in dir(x) if not i.startswith("__")]
  • “我想我必须覆盖__dict__” - 不要那样做。它打破了太多的期望和太多的代码。他们用namedtuple 尝试过,这是个坏主意,他们不得不改回来。
  • @juanpa.arrivillaga 我不知道有什么区别。感谢您指出。
  • @JosepValls 如果我添加一个方法,它将被包括在内,因为它不是以__ 开头的。也许我应该过滤掉所有功能?

标签: python class dictionary


【解决方案1】:

这里的根本问题是dir 返回:

Else, return an alphabetized list of names comprising (some of) the attributes
    of the given object, and of attributes **reachable** from it

foo不是实例的属性,它是类的属性,从实例可达,因此它包含在 dir 输出中,但不在实例的 __dict__ 中。检查Example.__dict__类块中定义的 Python 中的一切都将属于类。但是在__init__ 方法中,您明确分配self.foo = val,它分配给实例

考虑:

In [2]: e = Example()

In [3]: e.__dict__
Out[3]: {'foo': 1}

In [4]: Example.__dict__
Out[4]:
mappingproxy({'__dict__': <attribute '__dict__' of 'Example' objects>,
              '__doc__': None,
              '__init__': <function __main__.Example.__init__>,
              '__module__': '__main__',
              '__weakref__': <attribute '__weakref__' of 'Example' objects>,
              'bar': <property at 0x104214408>})

也许最简单的解决方案是利用dir 对属性可达的感知与以下过滤操作相结合:

In [12]: list(s for s in dir(e) if not callable(getattr(e, s)) and not s.startswith('__'))
Out[12]: ['bar', 'foo']

【讨论】:

    猜你喜欢
    • 2011-07-13
    • 2016-03-06
    • 1970-01-01
    • 2010-09-08
    • 1970-01-01
    • 2019-01-13
    • 2022-01-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多