<p>对于ide中的代码完成和类型提示,只需为<code>Person</code>和<code>Address</code>类添加静态类型,就可以了。假设您使用最新的<code>python3.6</code>,下面是示例中typescript类的大致等价物:</p>
<pre><code># spam.py
from typing import Optional, Sequence
class Address:
street: str
housenumber: int
housenumber_postfix: Optional[str]
def __init__(self, street: str, housenumber: int,
housenumber_postfix: Optional[str] = None) -> None:
self.street = street
self.housenumber = housenumber
self.housenumber_postfix = housenumber_postfix
class Person:
name: str
adresses: Sequence[Address]
def __init__(self, name: str, adresses: Sequence[str]) -> None:
self.name = name
self.adresses = adresses
person = Person('Joe', [
Address('Sesame', 1),
Address('Baker', 221, housenumber_postfix='b')
]) # type: Person
</code></pre>
<p>我想您提到的样板是在添加类构造函数时出现的。这确实是不可撤销的。我希望默认构造函数在运行时生成,而不是显式声明,如下所示:</p>
<pre><code>class Address:
street: str
housenumber: int
housenumber_postfix: Optional[str]
class Person:
name: str
adresses: Sequence[Address]
if __name__ == '__main__':
alice = Person('Alice', [Address('spam', 1, housenumber_postfix='eggs')])
bob = Person('Bob', ()) # a tuple is also a sequence
</code></pre>
<p>但不幸的是你必须手工申报。</p>
<hr/>
<h3>编辑</h3>
<p>正如<a href="https://stackoverflow.com/users/646543/michael0x2a">Michael0x2a</a>在<a href="https://stackoverflow.com/questions/48254562/python-equivalent-of-typescript-interface/48255117#comment83496184_48255117">comment</a>中指出的,在引入<code>python3.7</code>装饰器的<code>@dataclass</code>中,可以避免对默认构造函数的需要,因此可以声明:</p>
<pre><code>@dataclass
class Address:
street: str
housenumber: int
housenumber_postfix: Optional[str]
@dataclass
class Person:
name: str
adresses: Sequence[Address]
</code></pre>
<p>并获得几个方法的默认impl,从而减少样板代码的数量。查看<a href="https://www.python.org/dev/peps/pep-0557/" rel="noreferrer">PEP 557</a>了解更多详细信息。</p>
<hr/>
<p>我想您可以看到从代码生成的存根文件,作为某种接口文件:</p>
<pre><code>$ stubgen spam # stubgen tool is part of mypy package
Created out/spam.pyi
</code></pre>
<p>生成的存根文件包含模块的所有非私有类和函数的类型化签名,但没有实现:</p>
<pre><code># Stubs for spam (Python 3.6)
#
# NOTE: This dynamically typed stub was automatically generated by stubgen.
from typing import Optional, Sequence
class Address:
street: str
housenumber: int
housenumber_postfix: Optional[str]
def __init__(self, street: str, housenumber: int, housenumber_postfix: Optional[str]=...) -> None: ...
class Person:
name: str
adresses: Sequence[Address]
def __init__(self, name: str, adresses: Sequence[str]) -> None: ...
person: Person
</code></pre>
<p>IDE也可以识别这些存根文件,如果原始模块不是静态类型的,它们将使用存根文件进行类型提示和代码完成。</p>