Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/282.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 将类名传递给字典(和解析顺序)_Python_Class_Parsing - Fatal编程技术网

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

Python 将类名传递给字典(和解析顺序),python,class,parsing,Python,Class,Parsing,我有一些代码如下所示: class Action(object): ... class SpecificAction1(Action): ... class SpecificAction2(Action): ... 它们都在同一个文件中指定。在他们的规范之前,我想放一本字典如下所示: ACTIONS = { "SpecificAction1": SpecificAction1, "SpecificAction2": SpecificAction2 }

我有一些代码如下所示:

class Action(object):
    ...

class SpecificAction1(Action):
    ...

class SpecificAction2(Action):
    ...
它们都在同一个文件中指定。在他们的规范之前,我想放一本字典如下所示:

ACTIONS = {
    "SpecificAction1": SpecificAction1,
    "SpecificAction2": SpecificAction2
}
我的想法是,我可以简单地从其他模块导入ACTIONS字典,并将这一字典作为操作的一个规范字符串表示(它们通过网络和其他需要一些标识符的地方发送)

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


此外,如果可以执行上述操作,我是否可以执行此操作来实例化一个类:
ACTIONS['SpecificAction2']()

是的,您可以执行此操作。Python是一种动态语言,它允许您这样做。但是,从
操作
dict中,这些值是类的定义。如果您想通过网络提供它们,请将它们作为字符串传递,并使用
getattr

ACTIONS = {
    "SpecificAction1": 'SpecificAction1',
    "SpecificAction2": 'SpecificAction2'
}
并导入包含以下定义的文件:

module = __import__('my_actions_module')
class_ = getattr(module,ACTIONS.get('SpecificAction1'))
instance = class_()
实例
就是您所需要的。

类是用Python编写的,也就是说,您可以像对待任何其他对象一样对待它们。从这个角度来看,您的构造非常好,除了必须在文件末尾定义
ACTIONS
dictionary(因为与其他一些语言不同,Python中的顺序很重要:否则会抛出ReferenceError)

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

ACTIONS={}
类MyMeta(类型):
定义初始值(cls、名称、基数、nmspc):
超级(MyMeta,cls)。\uuuuu init\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu

如果名称!=“操作”:#我的观点是,关键将是我在电线上输入的字符串名称。通过这种方式,我可以将实现保留在该字典中(假设两端运行相同的代码),并使用另一个类将其切换出去,而不会影响用于表示该操作的名称。如果要将实现保留在字典中,您将无法那么容易地找到键。如果你想通过网络发送dict,你应该使用。
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):
    ...