我有这个文件结构:
- package
- sub_package_1
- __init__.py
- sub_module_1.py
- sub_package_2
- __init__.py
- sub_module_2.py
在
sub_module_1.py
中我们有这样的代码:
class A:
def __init__(self):
self.b = B()
def method_a(self, var: int):
pass
class B:
def __init__(self):
pass
def method_b(self, var: int):
pass
class C: # This class always located in different module, but for example lets place it here
def __init__(self):
self.a = A()
def method_c(self, var: int):
pass
a = A()
a.b.method_b() # here we have an argument warning (method_b is waiting for an argument)
c = C()
c.a.b.method_b() # and also here, the same warning
在
sub_module_2.py
中我们有这样的代码:
from package.sub_package_1.sub_module_1 import A
class C:
def __init__(self):
self.a = A()
def method_c(self, var: int):
pass
c = C()
c.a.b.method_b() # but here we don't have a warning
我在代码中留下了一些注释来显示问题。
当我在同一个模块(甚至在同一个包)中工作时,我可以看到由方法参数引起的所有警告。但是,如果我将其中一个类移到包外(就像我对
C
类所做的那样),我就会松开所有警告。我仍然可以自动完成行,有打字提示等,但如果我没有在 c.a.b.method_b()
中传递任何参数,我不会收到任何警告。
我觉得这是一个导入问题,但我找不到解决方案。
这种行为的原因是什么?我该如何解决它?
如所写,
c.a
的推断类型是Any
,这意味着您可以用它做任何事情,并且mypy
(以及可能的其他工具)会很高兴。这包括假设 c.a
具有属性 b
和 0 参数方法 method_b
。
这是因为您没有为各种
__init__
函数提供任何注释,这使得 mypy
本质上忽略它们以及它们产生的任何内容。
为
None
方法提供显式的 __init__
返回类型,即使跨越导入边界,您也应该得到预期的错误。
class B:
def __init__(self) -> None:
pass
def method_b(self, var: int):
pass