从字典描述创建对象

Create objects from dictionary description

Python MongoDB 驱动程序,PyMongo,returns 结果作为字典。我正在尝试找出在对象构造函数中使用此类字典的最佳方法。

  1. 将字典作为属性保存

    self.dict = building_dict
    

    然后建筑物的每个 属性 都可以通过 building.dict["property"] 到达。

    可以使用更好的属性名称。也许是一个字母属性。这看起来不太优雅。

  2. 解析字典以创建属性

    self.name = building_dict['name']
    self.construction_date = building_dict['construction_date']
    ...
    

    在我的模型中,字典可能非常大,但 this task can be automated 在构造函数中对赋值前后的值执行 actions/checks。

编辑:getters/setters 的使用与上面的选项 1. 和 2. 无关。

在解决方案 2 中,我通过在所有字典键前加上下划线前缀来避免属性和它们的 getter 之间的名称冲突,然后再将它们设为属性。

作为附带问题,字典可能包含嵌入文档的描述,因此构造函数应遍历整个字典以查找在代码中具有特定 class 的嵌入文档并实例化那些 class马上就可以了。

更新

我很可能会为我的项目使用 ODM,例如 MongoEngine,它会处理这些问题。

在这个特定的用例之外(link 和 MongoDB,现有的 ODMs,...),这个问题仍然相关,所以我离开最好的我能想到的答案。

您最多只能创建一个 object。您可以像这样用 dict 实例化 class

building_dict = {'property': 4, 'name': 'my name'}   # example dict
my_item = type('MyClass', (), building_dict)         # instantiating class MyClass

之后您可以像访问所有其他对象一样访问它:

print(my_item.property)
# 4
print(my_item.name)
# my name

目前为止我最喜欢的解决方案将元素存储为属性并使用 getters/setters:

class Building(object):

    def __init__(self, dictionary):

        # Check the values
        # ...

        # Find sub-dictionaries describing instances of another class
        # stored as embedded documents in the base, call their 
        # constructor on sub-directories, then replace each sub-directory
        # with the corresponding class instance.
        # ...

        # Set attributes from dictionary
        for key in dictionary:
            setattr(self, '_'+key, dictionary[key])

        # Add default values if needed, etc.
        # ...

    # Usual getter/setter stuff
    @property
    def name(self):
        try:
            return self._name
        except AttributeError as e:
            # deal with missing name