【发布时间】:2016-06-17 01:14:02
【问题描述】:
现在可以在 python 3 中使用类型提示了。
在我的小脚本中,我希望使用类型提示。但是,特定变量可以有两种类型。 np.ndarray(表示位置)或CelestialBody(从中获取位置)。
该函数位于CelestialOrbit 类中。
现在 CelestialBody 对象没有在类之前定义,所以我使用前向引用,如 pep 所述
from math import pi
import numpy as np
import math as m
from numpy import cos, sin, sqrt, power, square, arctan2, arccos, arcsin, arcsinh, radians, degrees
from scipy.optimize import *
import scipy as sp
import celestial_body as CB
import typing
#....
def get_total_max_distance(self, ancestor_body: "CB.CelestialBody", eps=3*np.finfo(float).eps):
if self.parent == ancestor_body:
return self.apoapsis_distance
orbit_list = list(self.create_tree_branch(ancestor_body))
orbit_list.reverse()
return orbit_list[0]._get_total_max_distance(ancestor_body.getGlobalPositionAtTime(),
ancestor_body.getGlobalPositionAtTime(),
orbit_list[1:], eps)
这很好用。 Pycharm 理解类型并且看起来是正确的?现在我想改变它,让它明白它可以同时采用 CB.CelestialBody 和 np.ndarray 类型。 (已经声明了第二个)。我尝试根据pep使用联合:
def get_total_max_distance(self, ancestor_body: typing.Union["CB.CelestialBody",np.ndarray], eps=3*np.finfo(float).eps):
但是这会失败并显示以下备注:“AttributeError: 'module' object has no attribute 'CelestialBody'”
完整的追溯:
Traceback (most recent call last):
File "C:/Users/Paul/PycharmProjects/KSP_helper/main.py", line 5, in <module>
from celestial_body import *
File "C:\Users\Paul\PycharmProjects\KSP_helper\celestial_body.py", line 7, in <module>
import celestial_orbit as CO
File "C:\Users\Paul\PycharmProjects\KSP_helper\celestial_orbit.py", line 123, in <module>
class CelestialOrbit:
File "C:\Users\Paul\PycharmProjects\KSP_helper\celestial_orbit.py", line 579, in CelestialOrbit
def get_total_max_distance(self, ancestor_body: typing.Union["CB.CelestialBody",np.ndarray], eps=3*np.finfo(float).eps):
File "C:\Python34\lib\site-packages\typing.py", line 537, in __getitem__
dict(self.__dict__), parameters, _root=True)
File "C:\Python34\lib\site-packages\typing.py", line 494, in __new__
for t2 in all_params - {t1} if not isinstance(t2, TypeVar)):
File "C:\Python34\lib\site-packages\typing.py", line 494, in <genexpr>
for t2 in all_params - {t1} if not isinstance(t2, TypeVar)):
File "C:\Python34\lib\site-packages\typing.py", line 185, in __subclasscheck__
self._eval_type(globalns, localns)
File "C:\Python34\lib\site-packages\typing.py", line 172, in _eval_type
eval(self.__forward_code__, globalns, localns),
File "<string>", line 1, in <module>
AttributeError: 'module' object has no attribute 'CelestialBody'
我该怎么做?
按照 Kevin 的建议,正如预期的那样,错误会更容易一些(因为 celestial_orbit 模块是由 celestial_body 模块导入的,因此当 python 尝试实例化 CelestialOrbit 类时,CelestialBody 类还没有被实例化)。
C:\Python35\python.exe C:/Users/Paul/PycharmProjects/KSP_helper/main.py
Traceback (most recent call last):
File "C:/Users/Paul/PycharmProjects/KSP_helper/main.py", line 5, in <module>
from celestial_body import *
File "C:\Users\Paul\PycharmProjects\KSP_helper\celestial_body.py", line 7, in <module>
import celestial_orbit as CO
File "C:\Users\Paul\PycharmProjects\KSP_helper\celestial_orbit.py", line 125, in <module>
class CelestialOrbit:
File "C:\Users\Paul\PycharmProjects\KSP_helper\celestial_orbit.py", line 581, in CelestialOrbit
def get_total_max_distance(self, ancestor_body: typing.Union[CB.CelestialBody, np.ndarray], eps=3*np.finfo(float).eps):
AttributeError: module 'celestial_body' has no attribute 'CelestialBody'
Bakuriu 的建议 - 将 CB.CelestialBody 更改为 celestial_body.CelestialBody 似乎有效。然而,这对我来说非常不合逻辑 - 特别是因为非联合版本与 CB 别名一起使用。
【问题讨论】:
-
将
CB.CelestialBody更改为celestial_body.CelestialBody可以解决问题吗?我最初将此作为答案发布,但检查 PEP PyCharm 实际上应该能够解析CB.CelestialBody。可能是 PyCharm 没有正确实现 PEP,在这种情况下这是一个答案,您应该在 PyCharm 的错误跟踪器中打开一张票。 -
无论如何,这个错误看起来像一个真正的错误。我的意思是:上面写着
module object has no attribute,这意味着PyCharm 确实在评估CB作为一个模块并寻找CelestialBody。这听起来非常可疑。您能否提供一个最小的完整代码,我们可以使用它来重现错误?只需将这些模块复制到某处并开始删除不必要的代码(例如,方法的所有实现都可以更改为pass或完全删除),直到找到触发此错误的最小代码。 -
这种变化(
CB.CelesticalBody到celestial_body.CelestialBody)似乎解决了这个问题。但是python.exe报错。从 shell 调用python main.py会导致同样的错误。 -
我想知道如果你这样做
"typing.Union[CB.CelestialBody,np.ndarray]"会发生什么。免责声明:我从未使用过类型提示。 -
@Bakuriu:您的建议有效的原因是因为
celestial_body引发了NameError异常。这实际上并没有使类型定义正确;该名称将从不在其使用的上下文中起作用。如果 PyCharm 接受这一点,那么它就超出了规范。
标签: python python-3.5 type-hinting