attrs是用于减少样板的有用软件包。例子:

class SomeClass(object):
    a_number = attr.ib(default=42)
    list2_of_numbers = attr.ib(default=attr.Factory(list))

PyCharm不为生成的__init__方法提供代码完成功能,有没有插件可以做到这一点?或其他解决方法?

最佳答案

更新于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

我还尝试使用 stub 文件从类声明中删除虚拟__init__,以期删除.pyi(如果曾经支持),但是它没有用。

当然,这种方法首先会破坏使用attrs的目的(即减少类声明样板,辅助可维护性等)。

如果添加,删除或修改attr.ib(),则需要记住手动更新__init__签名,这与attrs的原理背道而驰。

仅供引用,Jonas Obrist tweeted one of the Jetbrains Devs关于今年早些时候关于2017.3版本的attrs支持,所以手指交叉了……

编辑

实际上,有一个更可口的解决方法。只需将init=False传递给attr.s并按照通常的方式定义__init__方法即可。您仍然没有充分利用attrs的全部魔力,但是,嘿……总比没有好。

注意在您的手动__init__中初始化默认值,而不是针对该类初始化attr.ib声明。根据the docs,attr.ib的默认值将仅在attrs生成的__init__内初始化。

除此之外,据我所知,您仍然可以使用其他dunder方法,验证和所有其他优点。
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)

关于python - 用于attrs的Pycharm插件?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/44672465/

10-14 04:10