【问题标题】:Python: How to refer a class inside itself?Python:如何在自身内部引用一个类?
【发布时间】:2016-12-02 05:36:34
【问题描述】:

试图在自身内部引用一个类。例如

class Test:
    FOO_DICT = {1 : Test.bar}  # NameError: name 'Test' is not defined

    @staticmethod
    def bar():
        pass

这种用法有意义吗?有更好的选择吗? 谢谢!

【问题讨论】:

  • 只使用bar 本身。
  • @DYZ 那行不通,因为 bar 还没有定义。
  • 正如下面有人建议的那样,更改定义的顺序。
  • 如果您不介意使用实例属性,您可以在 __init__ 中定义 self.FOO_DICT = {1: self.bar}

标签: python class self-reference


【解决方案1】:

如果要字典在类中:先定义函数,去掉Test:

class Test:
    @staticmethod
    def bar():
         pass

    FOO_DICT = {1: bar}

【讨论】:

  • 可能应该避免排序依赖,但似乎没有更好的模式。
【解决方案2】:

您可以像这样将FOO_DICT = {1 : Test.bar} 移出课堂:

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

【讨论】:

  • 这违反了类封装,应该避免。
【解决方案3】:

使用 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)

但是,在某些情况下,您确实需要使用一个类本身。 (请注意在所问问题的场景中。为此,只需使用 bar 而不添加如上所述的 Test )。 例如

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 可能会改变它的默认行为,因此到那时我们将不需要下面的解决方案)。

但是,如果您使用的是 3.7+ 的 Python 版本并且您不能在其内部引用一个类,那么简单的解决方案是 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 之前的版本将不支持此操作

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-13
    • 1970-01-01
    相关资源
    最近更新 更多