PyCharm 可以自动生成 __eq__() 和 __hash__() 实现吗?

Can PyCharm automatically generate __eq__() and __hash__() implementations?

我是 PyCharm 新手,但我是 IntelliJ 的长期用户。在 IntelliJ 中,当您编写 class 定义时,IDE 可以根据实例变量自动生成构造函数、equals() 方法和 hashCode() 方法。这不仅有利于节省打字时间,还能防止无意中的错误并自动引入一些 equals()hashCode() 最佳实践。

我希望 PyCharm 可以做同样的事情,因为产品来自同一家公司。在对文档进行大量谷歌搜索和搜索之后,我找不到 __eq__()__hash__() 的任何内容。当然,Python 实例变量没有明确指定,但我希望生成器可以遵循一个约定,比如提供所有 __init()__ 参数作为潜在的实例变量。至于__init__(),我把found something that will automatically add instance variable settings改成了__init__(),但是这种方式看起来比直接打字还要麻烦,而且它甚至没有将实例变量作为参数添加到__init__() ] 签名.

我是否遗漏了文档中的任何内容,或者也许有一个插件可以做到这一点?

Update:明确地说,我正在寻找能够生成这些方法的实际实现的东西。也就是说,如果我有一个名为 Point 的 class,并且 PyCharm 知道我的 class 有 xy 实例变量,那么它将为 __eq__() 方法自动生成:

def __eq__(self, other):
    if not isinstance(other, Point):
        return NotImplemented
    elif self is other:
        return True
    else:
        return self.x == other.x and self.y == other.y

等价物在 IntelliJ 中很容易完成。

Select class 然后执行以下操作之一:

  • Alt-Insert
  • Right Click -> Generate
  • Menu -> Code -> Generate

您可以创建 Live Template

在文件->设置->编辑器->实时模板下 寻找 Python 单击 + 添加,然后我将我的命名为 "class" 并确保在 gui 中为 Python 个文件添加上下文。

模板文本:

class $class_name$:
    """$class_docstring$"""

    def __init__(self, $args$):
        """$init_docstring$"""
        pass

    def __eq__(self, $other$):
        if not isinstance($other$, $class_name$):
            return NotImplemented
        elif self is $other$:
            return True
        else:
            return self.$eq_field$ == $other$.$eq_field$

    def __hash__(self, ):
        pass
    $END$

我将 "Options" -> "Expand with" 部分设置为 "Default (Tab)" 在此之后,当您键入 "class" 时,您可以使用 Tab 自动完成来插入实时模板。您的光标将跳到实时模板文本中作为变量包含的任何部分。

比较复杂,即列表类型,LiveTemplate 似乎不支持变量。例如,实时模板文本中的条件句或列表扩展似乎不可用。

也许数据的概念 classes 也可能对您感兴趣?

https://docs.python.org/3/library/dataclasses.html

这是文档中的示例:

from dataclasses import dataclass

@dataclass
class InventoryItem:
    """Class for keeping track of an item in inventory."""
    name: str
    unit_price: float
    quantity_on_hand: int = 0

    def total_cost(self) -> float:
        return self.unit_price * self.quantity_on_hand

注释从 class 上的注释类型隐式生成默认方法。我知道这不是您问题的答案(因为实际上看不到生成的代码)但可能有助于解决您提出问题的原因。