Python:如何在类内部引用自身类?

14
尝试在类内部引用其本身。例如:
class Test:
    FOO_DICT = {1 : Test.bar}  # NameError: name 'Test' is not defined

    @staticmethod
    def bar():
        pass

这种用法有意义吗?有更好的替代方案吗? 谢谢!


只需使用 bar 本身。 - DYZ
@DYZ 这样做不行,因为 bar 还没有被定义。 - Christian Dean
正如下面有人建议的那样,改变定义的顺序。 - DYZ
如果您不介意使用实例属性,您可以在__init__中定义self.FOO_DICT = {1: self.bar} - Guimoute
3个回答

10

您不需要在类内部引用自身,使用bar而不是Test.bar即可正常工作。

class Test:
    @staticmethod
    def bar():
        pass

    FOO_DICT = {1: bar}


# You can access this outside of the class by simply using Test.FOO_DICT
print(Test.FOO_DICT)

然而,在某些情况下,你确实需要使用一个类本身。例如

class Test:
    @staticmethod
    def bar():
        pass

    def test_with_other_of_same_instance(self, other: Test):
        print(other.FOO_DICT)

    FOO_DICT = {1: bar}

在这种情况下,
  • 我想定义一个接受相同Test类的对象的方法。
  • 我希望使用Python的类型提示来指示预期的参数是Test类的实例。这允许我获得编辑器支持,并且像Pylance和Mypy这样的工具可以在我传递了错误的数据类型的参数时通知我可能存在的错误。

在撰写本文时,我会得到一个NameError: name 'Test' is not defined。

这是因为默认情况下无法在类内部使用类自身(随着Python版本的更新,其默认行为可能会发生改变,因此到那个时候我们将不需要下面的解决方案)。

但是,如果您使用的是Python 3.7+版本且不能引用自身的类,则PEP 563 - 推迟注释评估提供了简单的解决方案。通过在文件的第一行添加一行代码来实现。

from __future__ import annotations
# other imports or code come afterwards


class Test:
    @staticmethod
    def bar():
        pass

    def test_with_other_of_same_instance(self, other: Test):
        print(other.FOO_DICT)

    FOO_DICT = {1: bar}

如果在Python中使用一个类内部的类,只需在文件开头包含该行即可。

通常情况下,如果使用Pylance或任何类似的工具,您会收到警告或错误显示,以便告诉您导入了某些内容但未使用。但在注释的情况下不需要担心编辑器的任何警告。

请注意,这必须发生在文件开头,否则您将获得SyntaxError,并且早于3.7版本的版本不支持此功能。


5
如果您想让字典在类中使用:先定义该函数,然后删除Test。
class Test:
    @staticmethod
    def bar():
         pass

    FOO_DICT = {1: bar}

可能应该避免排序依赖,但似乎没有更好的模式。 - cheng

0
你可以像这样将 FOO_DICT = {1 : Test.bar} 移到类外面:

class Test:
    @staticmethod
    def bar():
         pass
Test.FOO_DICT = {1: Test.bar}

6
这违反了类的封装性原则,应该避免这样做。 - DYZ

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接