ChatGPT解决这个技术问题 Extra ChatGPT

为什么 PyCharm 建议将方法更改为静态?

新的 pycharm 版本(3.1.3 社区版)建议将不适用于当前对象状态的方法转换为静态。

https://i.stack.imgur.com/l0TgW.png

这样做的实际原因是什么?某种微性能(或内存)优化?

@Wooble:有 return 1 作为该方法的单行实现。 “更多”不包含任何有用的东西

j
jolvi

PyCharm“认为”您可能想要拥有一个静态方法,但您忘记将其声明为静态(使用 @staticmethod 装饰器)。

PyCharm 提出这一点是因为该方法在其主体中没有使用 self,因此实际上没有更改类实例。因此,该方法可以是静态的,即无需传递类实例或什至无需创建类实例即可调用。


很多人都回答了这种风味反应。不过,我要补充一点,如果您知道它肯定不会是静态方法,那么在您在那里时包含一个“抛出 NotImplementedError”,以确保在未完成它的情况下不使用它。
在某些情况下,PyCharm 的警告可能是不合理的,因为我们既不需要静态方法也不需要更改状态。另一方面,如果该方法尚未实现,那么提出 NotImplementedError 似乎总是一个好主意。
我的默认实现返回一个常量,但我的子类可以根据 self 返回一个值。在这种情况下,警告是可以忽略的,我用 # noinspection PyMethodMayBeStatic 标记它。遗憾的是,IntelliJ IDEA 没有提供在上下文菜单中为这个警告添加这个禁用注释。
我建议在 PyCharm 的首选项中将此 PyCharm 检查的严重性从“警告”更改为“不突出显示,仅修复”。 (它给我带来了很多误报。)
B
Bob Stein

同意@jolvi、@ArundasR 和其他人的意见,警告发生在不使用 self 的成员函数上。

如果您确定 PyCharm 是错误的,该函数不应该是 @staticmethod,并且如果您重视零警告,您可以通过两种不同的方式消除此警告:

解决方法 #1

def bar(self):
    self.is_not_used()
    doing_something_without_self()

def is_not_used(self):
    pass

解决方法 #2 [谢谢@DavidPärsson]

# noinspection PyMethodMayBeStatic
def bar(self):
    doing_something_without_self()

我为此拥有的应用程序(我不能使用@staticmethod 的原因)是制作一个处理函数表以响应协议子类型字段。当然,所有处理程序必须是相同的形式(静态或非静态)。但有些人碰巧没有对实例做任何事情。如果我制作那些静态的,我会得到“TypeError:'staticmethod'对象不可调用”。

为了支持 OP 的惊愕,建议您尽可能添加 staticmethod,这与 principle 背道而驰,即以后减少代码限制比增加更多限制更容易 - 使方法静态现在减少限制,因为您可以调用 class.f() 而不是 instance.f()。

猜测为什么会出现这个警告:

它宣传静态方法。它使开发人员意识到他们很可能想要的东西。

正如@JohnWorrall 所指出的,当 self 无意中被排除在功能之外时,它会引起您的注意。

这是重新考虑对象模型的提示;也许这个函数根本不属于这个类。


“现在将方法设为静态可以减少限制” ---它根本没有。例如:多态方法
我认为最后一点值得重复:“你为什么要把它变成一种方法,而它显然是一个函数?”将真正需要实例的内容与处理某些方面的结构性内容分开。然后,您可以轻松地将其细分为单独的模块。
在方法或类上方添加 # noinspection PyMethodMayBeStatic 会抑制警告,并且在我看来比调用空方法更好。
@Talha:self 在 Python3 中根本没有被删除。
@Talha,我不明白你的意思。我想不出 Python 2 中的 self 在 Python 3 中不需要的任何方式。你能举个例子或链接吗?
P
Prune

我认为这个警告的原因是 Pycharm 中的配置。您可以在编辑器->检查中取消选中选择方法可能是静态的


我的问题是为什么会存在这样的检查。我知道我可以关掉它。对不起,没有答案。
不是问题的答案,但非常有用,谢谢!
C
Community

我同意这里给出的答案(方法不使用 self,因此可以用 @staticmethod 装饰)。

我想补充一点,您可能希望将该方法移动到顶级函数而不是类中的静态方法。有关详细信息,请参阅此问题和接受的答案:python - should I use static methods or top-level functions

将该方法移动到顶级函数也将修复 PyCharm 警告。


真正有用的答案 - 也许 PyCharm 应该将警告重命名为“方法可能是静态或顶级函数”。重构方法时,如果 self 不是参数,pycharm 将创建一个顶级函数而不是静态方法。
@tlo +1 用于提及装饰器。我有一个类,其方法不使用 self,因此可能是顶级的,但是,在查看此方法的作用时,这并不合乎逻辑 - 因为顶级它看起来更像是一个全局方法,虽然它实际上是从该类创建的实例的一个小辅助方法。所以为了让我的代码在逻辑上井井有条,装饰器是完美的解决方案。
J
Jan Vlcinsky

我可以想象将类方法定义为静态方法的以下优点:

您可以只使用类名调用该方法,无需实例化它。

如果存在的话,剩余的优势可能是微不足道的:

可能跑得快一点

节省一点内存


是的。但问题是 - 我没有将它用作静态方法。否则它已经是静态的了。所以 PyCharm 建议不要有充分的理由这样做(?)。 “如果存在的话,剩余的优势可能是微不足道的”——是的,确切地说。但如果是这样的话 - 这是 PyCharm 的一个愚蠢的建议
@zerkms 这就是它与一些迷人的实例的方式:-)
静态方法是构建好的软件的敌人。它们使许多原则无效,因此 bit 运行得更快不是重点(因为它们在 ram 中运行,因此在两种情况下都运行得很快),并且您知道计算机现在具有 bunch 内存,因此这不再是问题。另请注意您的第一个想法:这是一种程序行为,而不是面向对象的行为。
J
Junuxx

这可能有点混乱,但有时您只是不需要访问 self,但您更愿意将方法保留在类中,not 将其设为静态。或者你只是想避免添加一堆难看的装饰器。以下是针对这种情况的一些潜在解决方法。

如果您的方法只有副作用并且您不关心它返回的内容:

def bar(self):
    doing_something_without_self()
    return self

如果确实需要返回值:

def bar(self):
    result = doing_something_without_self()
    if self:
        return result

现在您的方法正在使用 self,警告消失了!


我建议不要这样做。为什么要让您的代码更加混乱和混乱,只是为了让特定 IDE 的警告消失?这只是一个警告,让您查看它。如果它不是最好的解决方案,你不必按照它所说的去做。 IDE 并不总是知道什么最适合您的代码。
C
Community

由于您没有在 bar 方法主体中引用 self,PyCharm 会询问您是否可能想要将 bar 设为静态。在其他编程语言(如 Java)中,声明静态方法的原因很明显。在 Python 中,静态方法 (AFIK) 的唯一真正好处是能够在没有类实例的情况下调用它。但是,如果这是您唯一的原因,您最好使用顶级函数 - 如注释 here

简而言之,我不能百分百确定它为什么会在那里。我猜他们可能会在即将发布的版本中删除它。


J
John Worrall

这个错误消息对我有很大帮助,因为我没有意识到我不小心使用我的测试示例播放器编写了我的函数

my_player.attributes[item] 

而不是正确的方法

self.attributes[item]

J
Junyu Wu

Pycharm 之所以将其作为警告,是因为 Python 在调用非静态方法(不添加 @staticmethod)时会将 self 作为第一个参数传递。 Pycharm 知道这一点。

例子:

class T:
    def test():
        print "i am a normal method!"

t = T()
t.test()
output:
Traceback (most recent call last):
  File "F:/Workspace/test_script/test.py", line 28, in <module>
    T().test()
TypeError: test() takes no arguments (1 given)

我来自 Java,在 Java 中“self”被称为“this”,你不需要在类方法中写 self(或 this)作为参数。您可以在方法中根据需要调用 self 。但是 Python“必须”将 self 作为方法参数传递。

通过理解这一点,您不需要任何解决方法作为@BobStein 的答案。


它通过了 self 那又怎样?
@zerkms '@staticmethod' 不传递 'self'
我刚刚引用了你:“Python 会将 self 作为第一个参数传递...... Pycharm 知道这一点。”。所以呢? Pycharm 知道,我知道。标记方法的原因是什么?
@zerkms 因为 Pycharm 认为您的第一个方法参数可能不是“自我”。通常 ppl 不会设计方法参数并且从不使用它。 Pycharm 认为您正在创建一个静态方法并且没有意识到第一个参数不是“自我”,因此默认情况下会发出警告。这种混乱是由编程语言设计引起的。我建议你按照程序设计(即使它看起来不是一个好的模式),添加“静态方法”,以避免混淆。如果你添加一个“自我”完全没问题,如果你愿意,就永远不要使用它。我所说的只是理解程序设计的另一种选择。
K
KalC

与其在特定的 IDE 中实施另一种方法来解决此错误,不如执行以下操作有意义? PyCharm 对这个实现没有任何建议。

class Animal:
    def __init__(self):
        print("Animal created")

    def eat(self):
        not self # <-- This line here
        print("I am eating")


my_animal = Animal()

我的问题是关于这个建议背后的理由,而不是解决方法。
了解。想知道这是否可以向解释器发出信号,表明这不是静态方法。