在Python3中将类实例化为未知变量名

1 投票
1 回答
792 浏览
提问于 2025-04-17 13:52

我想找到一种方法,可以根据一个未知的 nodeName 在不确定的 DOM 中实例化一个类(而不使用 eval())。

我想做的事情类似于这个伪代码,假设 node 是一个在 DOM 树中的 dom node

# create dom and get a node

class SuperNode(node):
    def __init__(self):
        # do narly node stuff

但是我想根据节点名称来创建类,而这个名称是未知的,就像这样。

makeInstance(SuperNode, node.nodeName, node)

为了更清楚,node.nodeName 是我希望用作实例变量名的节点名称。所以如果 node.nodeName = 'clarence',这就像这样实例化它(我稍后会考虑如何把节点名称按字母顺序排列,以符合类命名的规则):

clarence = SuperNode(node) ''' where node is the node specified 
                               by the name clarence'''

如果名称是已知的,构造函数会像这样:

makeInstance(SuperNode, 'clarence', node) ''' where clarance will be the 
                                              instantiated variable of 
                                              class SuperNode'''

这就像使用 setattrib 设置一个属性:

setattr(class instance, attribute, value)

在这里,属性可以在一个变量中定义。

如果有人问这些名称将如何被访问,它们会在另一个类中定义,这个类用于整体的 DOM,然后可以进行检查。

有没有办法做到这一点呢?

举个例子,有一个关于狗的 XML 文件,其中包含狗的名字、品种、生日等元素。每只狗将是我最初 DOM 类下的一个 superNode 类,所有属性会在每个 SuperNode 的实例中“神奇地”设置。

1 个回答

1

我终于明白我需要做什么了,遗憾的是,答案其实已经在上面了(适当的谦虚总是好的)。当你想把东西放进一个对象里时,只需要用 setattr,就像这样:

>>> class SuperClass():
...     def print_hello(self):
...         print('Hello, world!')

>>> class WrapperClass():
...     pass

>>> wrapper = WrapperClass()
>>> setattr(wrapper, 'clarence', SuperClass())

>>> wrapper.clarence.print_hello()
Hello, world!
>>> 

其实,我会在这个包装类里面使用代码,所以它会是:

setattr(self, 'clarence', SuperClass())

如果你想在全局范围内做这件事,可以用 globals() 来赋值,像这样:

>>> globals()['clarence'] = SuperClass()
>>> clarence.print_hello()
Hello, world!

撰写回答