从字典创建类实例?

9
我尝试从包含比类属性更多键的字典中创建类实例。我已经阅读了来自此链接的相同问题的答案: Creating class instance properties from a dictionary? 。问题在于我不能按照所需的方式编写类定义中的__init__,因为我正在使用SQLAlchemy声明式类定义。此外,type('className',(object,),dict)创建不需要的错误属性。 以下是我找到的解决方案:
dict = {'key1': 'value1', 'key2': 'value2'}
object = MyClass(**dict)

但是如果字典中有冗余的键,它就无法工作:

dict = {'key1': 'value1', 'key2': 'value2', 'redundant_key': 'redundant_value'}
object = MyClass(**dict) # here need to ignore redundant_key

除了直接删除字典 dict 中的所有重复键,还有其他解决方案吗?


1
什么是“redundant_key”? - rafaelc
你想如何为 MyClass 编写 __init__?抱歉,我不熟悉SQLAlchemy声明式类定义的风格。 - Paul Rooney
@RafaelCardoso 的“redundant_key”是指一个存在于字典中但不存在于类属性中的键。 - Demyanov
@PaulRooney __init__ 用于 MyClass,例如在这个答案中 https://dev59.com/Z3I-5IYBdhLWcg3w3cg8#1639197 - Demyanov
你知道将输入哪些键吗? - rafaelc
@RafaelCardoso 是的,我确切地知道所有类的属性和字典键,并且我可以直接从字典中删除所有“错误的键”,然后使用上面提到的解决方案。但是我不认为这是正确的方法。 - Demyanov
3个回答

14

使用classmethod筛选字典并返回对象。

这样,您就不必强制让__init__方法接受一个字典了。

import itertools

class MyClass(object):
    @classmethod
    def fromdict(cls, d):
        allowed = ('key1', 'key2')
        df = {k : v for k, v in d.iteritems() if k in allowed}
        return cls(**df)

    def __init__(self, key1, key2):
        self.key1 = key1
        self.key2 = key2

dict = {'key1': 'value1', 'key2': 'value2', 'redundant_key': 'redundant_value'}

ob = MyClass.fromdict(dict)

print ob.key1
print ob.key2

1

然后在你的__init__函数中添加一行代码,如下:self.__dict__.update(dict_you_want) - Paul Cornelius

1

在Python中,对象的一种特殊的魔术方法object.__dict__,它是一个字典或其他映射对象,用于存储对象的(可写)属性。 因此,通过提升这个特性...

class MyClass(object):
   def __init__(self, **entries):
      self.__dict__.update(entries))

dict = {'key1': 'value1', 'key2': 'value2', 'redundant_key': 'redundant_value'}

ob = MyClass(**dict)

注意:它不能处理嵌套字典...

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接