Python:未解析的静态变量类的引用

Python: Unresolved reference to class from static variable

所以我得到了这个代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class MyClass:

    ACTIONS = {
       "ACTION_A": MyClass.__a,
       "ACTION_B": MyClass.__b
    }

    @staticmethod
    def do(constant):
        ACTIONS[constant]()

    @staticmethod
    def __a():
        print("A")

    @staticmethod
    def __b():
        print("B")

我正在尝试将私有的a和b函数映射到静态字典,这样我就可以用do方法执行函数。

尝试运行此代码时,我得到错误:"未解析的引用"myclass",位于操作字典的每一行。

你知道如何使这个工作正常吗?


你不应该一开始就用一门课。您所要做的就是创建一个名称空间,为此使用一个模块。在一个包中创建一个新模块,并将所有功能都放在该包中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
def _a():
    print("A")

def _b():
    print("B")


ACTIONS = {
    'ACTION_A': _a,
    'ACTION_B': _b,
}

def do(constant):
    ACTIONS[constant]()

请注意,我使用了单下划线名称。Python在类中使用双下划线名称来创建一个附加的每类命名空间。MyClass.__a变成MyClass._MyClass__a以避免与子类冲突(这样它们可以自由地重用名称,而不必担心破坏超类的实现),python中没有隐私模型。

您可以使用decorator来注册_a_b函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
def do(constant):
    ACTIONS[constant]()

ACTIONS = {}

def action(name):
    def decorator(f):
        ACTIONS[name] = f
        return f

@action('ACTION_A')
def _a():
    print("A")

@action('ACTION_B')
def _b()
    print("B")

您看到的具体错误是由于在完成整个class语句之前没有设置MyClass名称。以后你得把字典编好:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class MyClass:
    @classmethod
    def do(cls, constant):
        cls.ACTIONS[constant]()

    @staticmethod
    def _a():
        print("A")

    @staticmethod
    def _b():
        print("B")

MyClass.ACTIONS = {
    'ACTION_A': MyClass._a,
    'ACTION_B': MyClass._b,
}

注意,do是一个类方法,你不能只访问ACTIONS作为一个全局,你需要使用MyClass.ACTIONS或者像我上面使用的那样,一个类方法然后引用cls上的对象。

您可以通过使用名称将class语句后面的ACTIONS设置为类方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class MyClass:
    ACTIONS = {
        'ACTION_A': '_a',
        'ACTION_B': '_b',
    }

    @classmethod
    def do(cls, constant):
        getattr(cls, cls.ACTIONS[constant])()

    @staticmethod
    def _a():
        print("A")

    @staticmethod
    def _b():
        print("B")