6

我有一个 Python 类,它存储一些字段并具有一些属性,例如

class A(object):
  def __init__(self, x, y):
    self.x = x
    self.y = y

  @property
  def z(self):
    return self.x+1

我需要对班级进行哪些更改才能做到

>>> a = A(1,5)
>>> dict(a)
{'y':5, 'z':2}

我在哪里指定我要返回yz?我不能只使用a.__dict__,因为它会包含x但不包含z. 我希望能够指定任何可以使用__getattribute__.

4

3 回答 3

13

向您的类添加一个__iter__()方法,该方法将对象项的迭代器作为键值对返回。然后,您可以将对象实例直接传递给dict()构造函数,因为它接受一系列键值对。

def __iter__(self):
    for key in "y", "z":
        yield key, getattr(self, key)

如果您希望这更灵活一点,并允许在子类(或以编程方式)上轻松覆盖属性列表,您可以将键列表存储为类的属性:

_dictkeys = "y", "z"

def __iter__(self):
    for key in self._dictkeys:
        yield key, getattr(self, key)

如果您希望字典包含所有属性(包括从父类继承的属性),请尝试:

def __iter__(self):
    for key in dir(self):
        if not key.startswith("_"):
            value = getattr(self, key)
            if not callable(value):
                yield key, value

这不包括以“_”开头的成员以及可调用对象(例如类和函数)。

于 2012-06-06T13:57:32.823 回答
5

我认为解决这个问题的合理方法是创建一种asdict方法。当您说要指定要 dict 包含哪些键时,我假设您对调用方法时传递的信息感到满意。如果这不是你的意思,请告诉我。(这包含kindall的优秀建议。)

class A(object):
    def __init__(self, x, y):
        self.x = x
        self.y = y

    @property
    def z(self):
        return self.x+1

    def asdict(self, *keys):
        if not keys:
            keys = ['y', 'z']
        return dict((key, getattr(self, key)) for key in keys)

测试:

>>> A(1, 2).asdict('x', 'y')
{'y': 2, 'x': 1}
>>> A(1, 2).asdict()
{'y': 2, 'z': 2}
于 2012-06-06T13:54:11.603 回答
0

解决此问题的一种天真的方法如下。它可能不足以满足您的需求,但我只是指出它以防您错过它。

>>> dict(y=a.y, z=a.z)
>>> {'y': 5, 'z': 2}
于 2012-06-06T13:56:26.530 回答