类型提示:解决循环依赖
Type hints: solve circular dependency
以下生成 NameError: name 'Client' is not defined
。我该如何解决?
class Server():
def register_client(self, client: Client)
pass
class Client():
def __init__(self, server: Server):
server.register_client(self)
您可以通过使用 字符串 名称来使用 forward reference 尚未定义的 Client
class:
class Server():
def register_client(self, client: 'Client')
pass
As of Python 3.7,您还可以通过在模块顶部添加以下 __future__
导入来推迟注释的 all 运行时解析:
from __future__ import annotations
此时注释被存储为表达式的抽象语法树的字符串表示;您可以使用 typing.get_type_hints()
来解决这些问题(并解决上面使用的前向引用)。
详情见PEP 563 -- Postponed Evaluation of Annotations;此行为将成为 Python 4.0.
中的默认行为
如果您使用的是 Python 3.7+,请使用 from __future__ import annotations
in another answer. However, if you cannot use 3.7 yet due to OS limitation (like Cygwin as of 2019-06-03), you can use Forward References 模块来解决这些类型的 forward/circular 依赖问题。
请原谅这个人为的例子,但这应该可以说明这种方法的有用性。
class Server():
clients: list = None
def __init__(self):
self.clients=[]
def register_client(self, client: 'Client') -> None:
self.clients.append(client)
print('Client `%s` registered with server' % client.name)
def print_clients(self) -> None:
for i, client in enumerate(self.clients):
print('client %i: %s' % (i, client.name))
@staticmethod
def build_clone(server: 'Server') -> 'Server':
svr_new: Server = Server()
for client in server.clients:
svr_new.register_client(client)
return svr_new
class Client():
name: str = None
def __init__(self, name: str, server: 'Server'):
self.name = name
server.register_client(self)
svr = Server()
cli = Client('foo', svr)
svr.print_clients()
svr_clone = Server.build_clone(svr)
svr_clone.print_clients()
以下生成 NameError: name 'Client' is not defined
。我该如何解决?
class Server():
def register_client(self, client: Client)
pass
class Client():
def __init__(self, server: Server):
server.register_client(self)
您可以通过使用 字符串 名称来使用 forward reference 尚未定义的 Client
class:
class Server():
def register_client(self, client: 'Client')
pass
As of Python 3.7,您还可以通过在模块顶部添加以下 __future__
导入来推迟注释的 all 运行时解析:
from __future__ import annotations
此时注释被存储为表达式的抽象语法树的字符串表示;您可以使用 typing.get_type_hints()
来解决这些问题(并解决上面使用的前向引用)。
详情见PEP 563 -- Postponed Evaluation of Annotations;此行为将成为 Python 4.0.
中的默认行为如果您使用的是 Python 3.7+,请使用 from __future__ import annotations
请原谅这个人为的例子,但这应该可以说明这种方法的有用性。
class Server():
clients: list = None
def __init__(self):
self.clients=[]
def register_client(self, client: 'Client') -> None:
self.clients.append(client)
print('Client `%s` registered with server' % client.name)
def print_clients(self) -> None:
for i, client in enumerate(self.clients):
print('client %i: %s' % (i, client.name))
@staticmethod
def build_clone(server: 'Server') -> 'Server':
svr_new: Server = Server()
for client in server.clients:
svr_new.register_client(client)
return svr_new
class Client():
name: str = None
def __init__(self, name: str, server: 'Server'):
self.name = name
server.register_client(self)
svr = Server()
cli = Client('foo', svr)
svr.print_clients()
svr_clone = Server.build_clone(svr)
svr_clone.print_clients()