I get the error:
NameError: name 'OrgUnit' is not defined
class OrgUnit(object):
def __init__(self,
an_org_name: str,
its_parent_org_unit: OrgUnit= None
):
self.org_unit_name = an_org_name
self.parent_org_unit = its_parent_org_unit
def __str__(self):
if self.parent_org_unit:
parent_org_unit_name = self.parent_org_unit.__str__()
return parent_org_unit_name + "->" + self.org_unit_name
else:
return self.org_unit_name
if __name__ == '__main__':
ibm_worldwide = OrgUnit("IBM_Worldwide")
ibm_usa = OrgUnit("IBM_USA", ibm_worldwide)
ibm_asia = OrgUnit("IBM_Asia", ibm_worldwide)
ibm_china = OrgUnit("IBM_China", ibm_asia)
print(ibm_worldwide)
print(ibm_usa)
print(ibm_asia)
print(ibm_china)
I am sure this is a known paradigm, as it seems like a pretty common hierarchical class usage issue (a self referencing class). I know I could change the type of its_parent_org_unit to be object and it works, but this seems like the wrong thing to do, primarily since it scuppers my ability to check types in my calls. With its_parent_org_unit changed to be a type object I get the correct results:
IBM_Worldwide
IBM_Worldwide->IBM_USA
IBM_Worldwide->IBM_Asia
IBM_Worldwide->IBM_Asia->IBM_China
I am open to thoughts and suggestions. What is the most "pythonic" way to do this sort of thing?
PS: What is the name for this sort of "self referencing class" paradigm/problem, which I could use to look up other suggestions?
Your problem is that you want to use type hints but you want this class itself to be able to take arguments of its own type.
The type hints PEP (0484) explains that you can use the string version of the type's name as a forward reference. The example there is of a Tree data structure which sounds remarkably similar to this OrgUnit one.
For example, this works:
class OrgUnit(object):
def __init__(self,
an_org_name: str,
its_parent_org_unit: 'OrgUnit' = None
):
In Python 3.7, you will be able to activate postponed evaluation of annotations with from __future__ import annotations. This will automatically store annotations as strings instead of evaluating them, so you can do
from __future__ import annotations
class OrgUnit(object):
def __init__(self,
an_org_name: str,
its_parent_org_unit: OrgUnit= None
):
...
This is scheduled to become the default in Python 4.0.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With