使用特定字典初始化从 class 构建的对象

Initialize an object built from a class with a specific dictionary

目标是使用 __init__ 方法构建 class,该方法允许创建将使用特定字典初始化的对象。

详情:

一个文件mydicts.py是各种词典的集合。 从我打算创建的 class 构建的对象将被初始化为 mydicts.py.

中的字典之一

mydicts.py 示例:

dict1 = {k1:v1, k2:v2,...,kn:vn}
dict2 = {k1:v1, k2:v2,...,km:vm}
etc.

我的尝试:

class Example(dict):
    def __init__(self, dictx):
        self.dictx = getattr(__import__("mydicts", fromlist=['m']), dictx)

结果:

e = Example('dict1')
print e
{}        # <- got empty dictionary. Want {k1:v1, k2:v2,...,kn:vn}

目标是创建这样的对象:

a = Example(dict1)
print a
# {k1:v1, k2:v2,...,kn:vn}

b = Example(dict2)
print b
# {k1:v1, k2:v2,...,km:vm}

由于您没有为 class 定义自定义 __str__ methodprint 正在调用父 class [=16] 的 __str__ 方法=].此外,这导致 Python 打印父 class 在 dict.__new__ 中创建的空字典,而不是您存储在 self.dictx.

中的字典

因为您的 class 继承自 dict,您应该将 getattr 返回的字典传递给父 class 的 __init__ 方法。您可以为此使用 super

class Example(dict):
    def __init__(self, dictx):
        dct = getattr(__import__("__main__", fromlist=['m']), dictx)
        super(Example, self).__init__(dct)

这将使用从 dct 获取的数据初始化父 class。换句话说,空字典已被 getattr 返回的字典替换。所以,当print调用父类的__str__方法时,会给出正确的输出:

>>> dict1 = {'k1':'v1', 'k2':'v2', 'kn':'vn'}
>>> class Example(dict):
...     def __init__(self, dictx):
...         dct = getattr(__import__("__main__", fromlist=['m']), dictx)
...         super(Example, self).__init__(dct)
...
>>> e = Example('dict1')
>>> print e
{'k2': 'v2', 'k1': 'v1', 'kn': 'vn'}
>>>

另一种解决方案是为您的 class 定义自定义 __str__ 方法,将 returns self.dictx 作为字符串:

class Example(dict):
    def __init__(self, dictx):
        self.dictx = getattr(__import__("mydicts", fromlist=['m']), dictx)
    def __str__(self):
        return str(self.dictx)

但是请注意,如果您使用这种方法,则没有真正的理由从 dict 继承,因为您的 class 不是一种新型字典;它只是将字典存储为属性。

我认为您使这件事变得比实际需要的复杂得多。注意到 the manual says:

Direct use of __import__() is rare, except in cases where you want to import a module whose name is only known at runtime.

但是您在加载时确实知道模块名称,只是您的数据定义有太多变量名称。更清楚的是 my_dicts.py:

my_dicts = [
    {k1:v1, k2:v2,...,kn:vn},
    {k1:v1, k2:v2,...,km:vm},
    …
]

example.py

import my_dicts

class Example(dict):
    def __init__(self, n):
        """Returns an Example instance loaded with the nth element
           of my_dict."""
        super(Example, self).__init__(my_dicts.my_dicts[n])