为什么可以这样
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
检查类型,这是 not true。
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。
答案 0 :(得分:7)
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
。
Python 3.7之前的解决方案
如果您不能或不想升级到Python> = 3.7,则可以使用字符串文字注释(我链接到的PEP中也提到了):
def add_ship(self, ship: 'Ship'):