The following produces NameError: name 'Client' is not defined. How can I solve it?
class Server():
def register_client(self, client: Client)
pass
class Client():
def __init__(self, server: Server):
server.register_client(self)
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
You can use a forward reference by using a string name for the not-yet-defined Client class:
class Server():
def register_client(self, client: 'Client')
pass
As of Python 3.7, you can also postpone all runtime parsing of annotations by adding the following __future__ import at the top of your module:
from __future__ import annotations
at which point the annotations are stored as string representations of the abstract syntax tree for the expression; you can use typing.get_type_hints() to resolve those (and resolve forward references as used above).
See PEP 563 — Postponed Evaluation of Annotations for details; this behaviour will be the default in Python 4.0.
Method 2
If you are on Python 3.7+, use from __future__ import annotations as mentioned 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 module to satisfy these types of forward/circular dependency issues.
Pardon the contrived example but this should illustrate the usefulness of this methodology.
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()
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0