【问题标题】:Why does ordering matter in type hinting?为什么排序在类型提示中很重要?
【发布时间】:2021-10-07 00:48:25
【问题描述】:

为什么会这样

class Ship:

    def __init__(self, parent):
        self.parent = parent

class Fleet:

    def __init__(self):
        self.ships = []

    def add_ship(self, ship: Ship):
        self.ships.append(ship)

但这不是?

class Fleet:

    def __init__(self):
        self.ships = []

    def add_ship(self, ship: Ship):
        self.ships.append(ship)

class Ship:

    def __init__(self, parent):
        self.parent = parent

我知道您在导入时不能有循环引用。但是,这不是导入的东西:它们都在同一个文件中。在这两种情况下,都定义了 Ship,但似乎如果首先定义了 Fleet,它就找不到 Ship 的定义。如果我使用isinstance 来检查类型,这不是正确的。

def add_ship(self, ship):
    if isinstance(ship, Ship): # works fine
        self.ships.append(ship)

但是,这不允许我的 IDE (PyCharm) 查看定义和自动完成语法。

事实上,下面的设计模式似乎可以正常工作

class Fleet:

    def __init__(self):
        self.ships = []

    def add_ship(self, ship):
        if isinstance(ship, Ship):
            self.ships.append(ship)

class Ship:

    def __init__(self, parent):
        if isinstance(parent, Fleet):
            self.parent = parent

但是,同样,我的 IDE 不允许找出类型。这是 Python 3.6.5/Anaconda/Windows 10。

【问题讨论】:

    标签: python python-3.x type-hinting python-typing


    【解决方案1】:

    def add_ship(self, ship: Ship):定义时间进行评估。当时Ship还没有定义。

    if isinstance(ship, Ship): 仅在调用 add_ship 时进行评估。这将(希望)仅在定义 Ship 之后。

    PEP 563(在 Python 3.7 及更高版本中实现)通过使类型注释评估变得惰性来解决此问题。

    如果您升级,可以将from __future__ import annotations 添加到文件顶部,该示例将起作用。

    这将在 Python 4.0 中完全实现,这意味着将不再需要 from __future__ import annotations

    Pre Python 3.7 解决方案

    如果您不能或不想升级到 Python >= 3.7,您可以使用字符串文字注释(在我链接到的 PEP 中也提到过):

    def add_ship(self, ship: 'Ship'):
    

    【讨论】:

    • 第二种使用字符串字面量的方法看起来更可靠,但它有什么我们应该注意的缺点吗?
    • 另外,如果您需要接受多个类型的参数(即Ship和Ferry),使用字符串文字注释方法时的语法是什么?
    猜你喜欢
    • 2015-07-11
    • 2016-04-06
    • 2016-11-13
    • 2016-03-31
    • 1970-01-01
    • 2017-03-09
    • 2016-10-18
    • 2010-12-03
    • 1970-01-01
    相关资源
    最近更新 更多