问题描述
我收到错误:
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)
我确信这是一个已知的范例,因为这似乎是一个非常常见的分层类使用问题(一个自引用类)。我知道我可以将 its_parent_org_unit
的类型更改为 object
并起作用,但这似乎是错误的选择这样做,主要是因为它削弱了我检查呼叫类型的能力。将 its_parent_org_unit
更改为类型 object
,我得到正确的结果:
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
我愿意接受思想和建议。做这种事情的最 pythonic方法是什么?
I am open to thoughts and suggestions. What is the most "pythonic" way to do this sort of thing?
PS:这种自我引用类范式/问题的名称是什么?我可以用来查找其他建议吗?
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.
类型提示PEP(0484)说明您可以使用。有一个 Tree
数据结构的示例,该数据结构听起来与此 OrgUnit
的结构非常相似。
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.
例如,这可以工作:
class OrgUnit(object):
def __init__(self,
an_org_name: str,
its_parent_org_unit: 'OrgUnit' = None
):
在Python 3.7中,您将能够激活。这将自动将注释存储为字符串而不是对它们进行评估,因此您可以从__future__导入注释
$ b中
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
):
...
已计划在Python 4.0中成为默认设置。
This is scheduled to become the default in Python 4.0.
这篇关于类型提示用于正在定义的类型的对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!