Python参数注释未解析的引用

时间:2018-03-20 19:41:09

标签: python python-3.x annotations

为什么说它找不到我的课?为什么我要创建另一个具有相同名称的类,以使其不抱怨?

from typing import Dict


class WeekDay:

    def __init__(self, day_number, day_name):
        self.day_name = day_name
        self.day_number = day_number

    @staticmethod
    def get_week_days() -> Dict[str, WeekDay]:  # WeekDay unresolved reference error
        weekdays = {
            "monday": WeekDay(1, "Monday"),
            "tuesday": WeekDay(2, "Tuesday"),
            "wednesday": WeekDay(3, "Wednesday"),
            "thursday": WeekDay(4, "Thursday"),
            "friday": WeekDay(5, "Friday"),
            "saturday": WeekDay(6, "Saturday"),
            "sunday": WeekDay(7, "Sunday")
        }
        return weekdays

3 个答案:

答案 0 :(得分:10)

来自文档(Section Forward references

  

当类型提示包含尚未定义的名称时,该定义可以表示为字符串文字,稍后要解决。

     

这种情况通常发生在a的定义中   容器类,其中定义的类出现在签名中   一些方法。

所以为了解决这个问题,只需用引号包装类型,如下所示:

from typing import Dict


class WeekDay:
    def __init__(self, day_number, day_name):
        self.day_name = day_name
        self.day_number = day_number

    @staticmethod
    def get_week_days() -> Dict[str, 'WeekDay']:  # quote WeekDay 
        weekdays = {
            "monday": WeekDay(1, "Monday"),
            "tuesday": WeekDay(2, "Tuesday"),
            "wednesday": WeekDay(3, "Wednesday"),
            "thursday": WeekDay(4, "Thursday"),
            "friday": WeekDay(5, "Friday"),
            "saturday": WeekDay(6, "Saturday"),
            "sunday": WeekDay(7, "Sunday")
        }

        return weekdays

答案 1 :(得分:3)

在Python3.7中,您可以使用: from __future__ import annotations

答案 2 :(得分:0)

你不能从自己的定义中引用一个类

Traceback (most recent call last):
    class A:
  File "/home/shmulik/so/ans.py", line 28, in A
    bar = A.foo
NameError: name 'A' is not defined

这会引发以下错误:

class A:
    def foo(self, x: 'A'):
        pass

作为解决此问题的方法,PEP484 - Type Hints(感谢@ ashwini-chaudhary的评论)允许将类定义写为字符串。

  

当类型提示包含尚未定义的名称时,即   定义可以表示为字符串文字,稍后要解决。

所以我们可以写一下:

class A:
    def foo(self):
        A.bar()

    @staticmethod
    def bar():
        print(42)


A().foo()

这个类将被python愉快地解释。

旁注

所以你在第一个例子中提到我们不能从它的定义中引用类,那么为什么这段代码有效呢?

foo()

此代码的工作原理是python解释器在类A的定义过程中跳过foo()方法定义的主体,并且仅在调用foo()时的最后一行跳过(并且定义了类A,python解释器执行A.bar()的主体并调用{{1}}。