将类名传递到字典(和解析顺序)

2024-09-30 20:28:33 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一些代码如下所示:

class Action(object):
    ...

class SpecificAction1(Action):
    ...

class SpecificAction2(Action):
    ...

它们都在同一个文件中指定。在他们的规格说明之前,我想放一本字典如下所示:

ACTIONS = {
    "SpecificAction1": SpecificAction1,
    "SpecificAction2": SpecificAction2
}

我的想法是,我可以简单地从其他模块导入ACTIONS字典,并让这一个字典成为动作的一个规范字符串表示(它们通过网络和其他需要标识符的地方发送)。你知道吗

有没有可能像做函数指针那样做“类指针”?我的编辑器抱怨说,在类定义之前声明字典之前,名称是未定义的-这是真的吗?你知道吗

另外,如果上述情况是可能的,我可以这样做来实例化一个类:ACTIONS['SpecificAction2']()?你知道吗


Tags: 模块文件字符串代码网络规范actions字典
2条回答

类在Python中是first-class citizens,也就是说,可以像对待任何其他对象一样对待它们。从这个角度来看,您的构造非常好,只是您必须在文件末尾定义ACTIONS字典(因为与其他一些语言不同,在Python中顺序很重要:否则它将抛出ReferenceError)。你知道吗

还有更多。您可以使用一些元编程来简化这个过程。考虑一下(Python2.x,语法在3.x中有点不同):

ACTIONS = {}

class MyMeta(type):
    def __init__(cls, name, bases, nmspc):
        super(MyMeta, cls).__init__(name, bases, nmspc)
        if name != "Action": # < - skip base class
            ACTIONS[name] = cls

class Action(object):
    __metaclass__ = MyMeta
    ...

class SpecificAction1(Action):
    ...

class SpecificAction2(Action):
    ...

它将自动用从Action类继承的任何类填充ACTIONS字典(因为Action类将MyMeta作为__metaclass__)。请在此处阅读有关元编程的更多信息:

https://python-3-patterns-idioms-test.readthedocs.org/en/latest/Metaprogramming.html

至于ACTIONS['SpecificAction2']():是的,它将创建一个类的新实例,这是非常有效的代码。你知道吗

是的,你能做到。Python是一种动态语言,它允许您这样做。但是,在ACTIONSdict中,这些值是类的定义。如果您想通过网络提供它们,请将它们作为字符串传递并使用getattr

ACTIONS = {
    "SpecificAction1": 'SpecificAction1',
    "SpecificAction2": 'SpecificAction2'
}

然后导入包含以下定义的文件:

module = __import__('my_actions_module')
class_ = getattr(module,ACTIONS.get('SpecificAction1'))
instance = class_()

instance就是你需要的。你知道吗

相关问题 更多 >