0

我有一些如下所示的代码:

class Action(object):
    ...

class SpecificAction1(Action):
    ...

class SpecificAction2(Action):
    ...

它们都在同一个文件中指定。在他们的规范之前,我想放一个看起来像这样的字典:

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

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

是否可以像做函数指针一样做这样的“类指针”?我的编辑抱怨在类定义之前声明字典之前未定义名称 - 这是真的吗?

另外,如果上述可能,我可以这样做来实例化一个类:ACTIONS['SpecificAction2']()

4

2 回答 2

1

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

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

他们导入包含定义的文件:

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

instance这就是你所需要的。

于 2013-07-31T12:44:18.517 回答
1

类是Python 中的一等公民,也就是说,您可以像对待任何其他对象一样对待它们。从这个角度来看,您的构造非常好,除了您必须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):
    ...

ACTIONS它会自动使用继承自 class 的任何类填充字典Action(因为Actionclass 具有MyMetaas a __metaclass__)。在此处阅读有关元编程的更多信息:

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

至于ACTIONS['SpecificAction2']():是的,它将创建该类的一个新实例,它是完全有效的代码。

于 2013-07-31T12:49:47.537 回答