【问题标题】:Overloading __dict__() on python class在 python 类上重载 __dict__()
【发布时间】:2014-04-23 18:26:05
【问题描述】:

我有一个类,我想将对象作为字典取回,所以我在__dict__() 中实现了这个。这是正确的吗?

我想一旦我这样做了,我就可以使用dict(自定义对象),并将对象作为字典取回,但这不起作用。

你应该超载__dict__()吗?如何使用dict() 将自定义对象转换为字典?

【问题讨论】:

    标签: python class


    【解决方案1】:

    __dict__ 不是 Python 对象的特殊方法。用于属性字典; dict() 从不使用它。

    相反,您可以支持迭代;当dict() 被传递一个产生键值对的iterable 时,就会产生一个带有这些键值对的新字典对象。

    您可以通过实现__iter__ 方法来提供可迭代对象,该方法应返回iterator。将该方法实现为生成器函数就足够了:

    class Foo(object):
        def __init__(self, *values):
            self.some_sequence = values
    
        def __iter__(self):
            for key in self.some_sequence:
                yield (key, 'Value for {}'.format(key))
    

    演示:

    >>> class Foo(object):
    ...     def __init__(self, *values):
    ...         self.some_sequence = values
    ...     def __iter__(self):
    ...         for key in self.some_sequence:
    ...             yield (key, 'Value for {}'.format(key))
    ... 
    >>> f = Foo('bar', 'baz', 'eggs', 'ham')
    >>> dict(f)
    {'baz': 'Value for baz', 'eggs': 'Value for eggs', 'bar': 'Value for bar', 'ham': 'Value for ham'}
    

    您还可以继承dict,或实现Mapping abstract class,dict() 将识别其中任何一个并将键和值复制到新的字典对象。这需要做更多的工作,但如果您希望自定义类在其他任何地方也能像映射一样发挥作用,那么这可能是值得的。

    【讨论】:

    • 似乎是合乎逻辑的,所以如果你想为 iter 传递一组选择的信息,你可以使用 return {"var1":"val1", ..." varn" : "valn"} 而不是 yield?
    • @josh1234:不,__iter__必须返回一个迭代器;字典本身不是迭代器。
    • @josh1234: 你需要生成一系列键值对。所以iter(somedictionary.items()) 可以,但不能直接somedictionary。
    • @josh1234:其他替代方案是 subclass dict 或以其他方式实现 Mapping abstract type。
    【解决方案2】:

    没有。 __dict__ 是一种用于自省的方法——它返回对象属性。你想要的是一种全新的方法,例如,称之为as_dict - 这是惯例。这里要理解的是,dict 对象不一定要使用dict 构造函数来创建。

    【讨论】:

    • 我更喜欢这个答案而不是投票最多的答案。很高兴知道dict 是如何工作的,但是覆盖__iter__ 以从对象中获取字典对我来说看起来有点笨拙。它也可能有一些意想不到的后果。
    • 我不会将__dict__ 称为自省方法。它是类的描述符,它的用途远远超出了自省;例如例如,当您覆盖 __setattr__ 时,您可以直接写入代码中实例的属性命名空间。
    【解决方案3】:

    以下方法将允许将类的对象强制转换为dict:

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

    【讨论】:

    • 这个答案对我来说是最清楚的。就我而言,我提供了一个键列表,而不是依赖于 self.__dict__
    猜你喜欢
    • 2011-06-20
    • 2014-06-25
    • 2012-05-16
    • 2011-04-07
    • 1970-01-01
    • 1970-01-01
    • 2018-01-08
    • 1970-01-01
    相关资源
    最近更新 更多