为什么排序在类型提示中很重要? [英] Why does ordering matter in type hinting?

查看:41
本文介绍了为什么排序在类型提示中很重要?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么没问题

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 来检查类型,这不是真的.

I know that you cannot have circular references in importing. However, this is not an import thing: both of these are in the same file. In both cases the definition of Ship is made, but it seems as though if Fleet is defined first it can't find the definition of Ship. This is not true if I used isinstance to check the type.

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

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

However, that does not allow my IDE (PyCharm) to see the definition and autocomplete syntax.

事实上,下面的设计模式似乎工作得很好

In fact, the following design pattern seems to work fine

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.

But, again, does not allow for my IDE to figure out the types. This is Python 3.6.5/Anaconda/Windows 10.

推荐答案

def add_ship(self, ship: Ship):定义时间求值.那个时候Ship还没有定义.

def add_ship(self, ship: Ship): is evaluated at definition time. At that time Ship is not defined yet.

if isinstance(ship, Ship): 仅在调用 add_ship 时计算.这将(希望)仅在 Ship 被定义之后.

if isinstance(ship, Ship): is evaluated only when add_ship is called. This will (hopefully) be only after Ship had been defined.

PEP 563(在 Python 3.7 及更高版本中实现)解决了这个问题使类型注释评估变得懒惰.

PEP 563 (implemented in Python 3.7 and above) solves this by making the type annotations evaluation lazy.

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

If you upgrade, you can add from __future__ import annotations to the top of the file and that example will work.

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

This will be fully implemented in Python 4.0, meaning from __future__ import annotations will not be needed.

Pre Python 3.7 解决方案

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

If you can't or don't want to upgrade to Python >= 3.7 you can use a string-literal annotation (which is also mentioned in the PEP I linked to):

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

这篇关于为什么排序在类型提示中很重要?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆