2018 年 8 月更新 - 根据 Hynek's Answer,PyCharm 2018.2 提供 attrs 支持。我迟到了一个月,因为我最近没有在 Python 中工作很多......
我的原始答案如下,虽然它仅适用于您使用 PyCharm 2018.1 或更低版本...
我知道的唯一解决方法(截至 PyCharm 2017.2.4)是在类声明中定义一个冗余的 __init__。 PyCharm 的代码完成可以使用此方法,但在运行时 attrs 生成的__init__ 将覆盖它。例如(type hints):
import attr
from typing import List, Optional
@attr.s
class SomeClass:
def __init__(self, a_number: int = 42,
list2_of_numbers : Optional[List[int]] = None) -> None:
...
a_number: int = attr.ib(default=42)
list2_of_numbers: List[int] = attr.ib(default=attr.Factory(list))
PyCharm code completion screen shot
我还尝试使用存根文件从类声明中删除虚拟__init__,以便在支持时删除 .pyi,但它不起作用。
当然,这首先违背了使用 attrs 的目的(即减少类声明样板,帮助可维护性等)
如果您添加、删除或修改 attr.ib(),您需要记住手动更新与 attrs 理念相反的 __init__ 签名。
仅供参考,Jonas Obrist tweeted one of the Jetbrains Devs 关于今年早些时候关于 2017.3 版本的 attrs 支持,所以祈祷...
编辑
实际上,有一个稍微更可口的解决方法。只需将init=False 传递给attr.s 并像往常一样定义您的__init__ 方法。您仍然没有充分利用 attrs 的 full 魔力,但是嘿……总比没有好。
注意在您的手册__init__ 中初始化您的默认值,而不是针对该类的 attr.ib 声明。根据the docs,attr.ib 的默认值只会在 attrs 生成的__init__ 内初始化。
除此之外,据我所知,您仍然可以获得其他笨拙的方法、验证和所有其他优点。
import attr
from typing import List, Optional
@attr.s(init=False)
class SomeClass:
a_number: int = attr.ib()
list2_of_numbers: List[int] = attr.ib()
def __init__(self, a_number: int = 42,
list2_of_numbers : Optional[List[int]] = None) -> None:
self.a_number: int = a_number
self.list2_of_numbers: List[int] = list2_of_numbers or []
# Replicate behaviour of attrs-generated __init__
attr.validate(self)