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


154

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

在此处输入图片说明

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


3
您是否单击了“更多...”?您self在方法内的任何地方引用了吗?(如果问题确实是“为什么PyCharm的设计师为什么要这样设计……您必须要问他们,而不是这样……)
Wooble 2014年

7
@Wooble:有return 1一个方法的单行实现。“更多”不包含任何有用内容
zerkms 2014年

Answers:


188

PyCharm认为您可能拥有一个静态方法,但是却忘记声明它是静态的(使用@staticmethod装饰器)。

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


4
有很多人回答了这种风味反应。不过,我要补充一点,如果您知道它绝对不是静态方法,那么在可以确定没有完成它的情况下不要使用它时,请添加“ throw NotImplementedError”。
理查德·格林

1
在某些情况下,PyCharm的警告不合理,因为我们既不希望使用静态方法,也不希望更改状态。另一方面,如果尚未实现该方法,则提出总是一个好主意NotImplementedError
jolvi

3
我的情况是我的默认实现返回一个常量,但是允许我的子类返回一个取决于的值self。在这种情况下,警告可以忽略,我用标记# noinspection PyMethodMayBeStatic。IntelliJ IDEA不提供在此警告的上下文菜单中添加此禁用注释的想法,这很可惜。
Alfe

我建议将PyCharm检查的严重性从“警告”更改为“不突出显示,只能修复”。(这给我带来许多误报。)
maciek

51

同意@ 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 ,这与后来使代码的限制性降低而不是使其变得更加限制性的原理背道而驰-使方法变为静态使其现在的约束性降低,因为您可以调用class.f()而不是instance.f()。

猜测为何存在此警告:

  • 发布staticmethod。它使开发人员意识到他们可能想要的东西。
  • 正如@JohnWorrall指出的那样,当self被无意中遗漏在函数之外时,它会引起您的注意。
  • 重新思考对象模型是一个提示。函数可能根本不属于此类。

1
“将方法设为静态使其现在受到的限制更少” ---完全没有。例如:多态方法
zerkms,2015年

我认为最后一点需要重复:“当它明显是一个函数时,为什么要使其成为方法?” 将真正需要实例的内容与处理某些方面的结构性内容分开。然后,您可以轻松地将其细分为单独的模块。
dhill

@dhill规则是美好的事物,直到您认为合理的例外为止。我描述了一个,回调列表。
鲍勃·斯坦

7
# noinspection PyMethodMayBeStatic在方法或类之上添加可抑制警告,并且在我看来比调用空方法更好。
大卫·派森(DavidPärsson)'17年

1
@Talha:self完全没有在Python3中删除。
Junuxx

12

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


12
我的问题是为什么还要进行这种检查。我知道我可以将其关闭。抱歉,没有答案。
zerkms

9

我同意此处给出的答案(该方法未使用self,因此可以用修饰@staticmethod)。

我想补充一点,您可能想将方法移至顶级函数,而不是将类中的静态方法移至该函数。有关详细信息,请参见此问题和可接受的答案:python-我应该使用静态方法还是顶层函数

将方法移至顶层函数也将修复PyCharm警告。


真正有用的答案-也许PyCharm应该将警告重命名为“方法可能是静态的或顶级功能”。重构方法时,pycharm将创建顶级函数,而不是静态方法(如果self不是参数的话)。
Suzana

@tlo +1提及装饰器。我有一类没有使用的方法,self因此可能是顶层的,但是,在查看此方法的作用时,这并不合逻辑-作为顶层,它看起来更像是全局方法,对于从该类创建的实例,实际上是一个小的辅助方法。因此,为了使我的代码合理地组织起来,装饰器是完美的解决方案。
卡西米尔

7

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

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

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

  • 可能会跑得更快
  • 节省一点内存

是的 但问题是-我没有将其用作静态方法。否则它将是静态的。因此,PyCharm建议您没有充分的理由(?)。“如果存在的话,剩下的优势可能就是微不足道的” ---是的。但是,如果是这样的话-这是PyCharm的愚蠢建议
zerkms 2014年

1
@zerkms这是一些迷人实例的处理方法:-)
Jan Vlcinsky 2014年

2
静态方法是构建优秀软件的敌人。它们使许多原则无效,因此,bit运行速度不是重点(因为它们在ram中都运行,所以在两种情况下都运行得很快),并且您知道计算机现在具有bunch内存,所以这不再是问题。还要注意您的第一个想法:这是一种过程行为,而不是面向对象的行为。
阿米尔·侯赛因(AmirHossein)

4

由于您未selfbar方法主体中进行引用,因此PyCharm会询问您是否要使其bar静态。在其他编程语言(如Java)中,显然有理由声明静态方法。在Python中,静态方法(AFIK)的唯一真正好处是无需类的实例即可调用它。但是,如果这是您的唯一原因,那么最好使用顶级功能-如此处所述

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


3

此错误消息对我有很多帮助,因为我还没有意识到我不小心使用测试示例播放器来编写函数

my_player.attributes[item] 

而不是正确的方法

self.attributes[item]

1

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

如果您的方法仅具有副作用,并且您不关心它返回的结果:

def bar(self):
    doing_something_without_self()
    return self

如果确实需要返回值:

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

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


0

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

例:

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

@zerkms“@staticmethod”不及格“自我”
俊宇武

我刚刚引用了您:“ Python将把self作为第一个参数,Pycharm知道这一点。” 所以呢?皮查姆知道,我知道。标记该方法的原因是什么?
zerkms

@zerkms,因为Pycharm认为您的第一个方法参数可能不是“自我”。通常,ppl不会设计方法参数,并且永远不会使用它。Pycharm认为您正在创建静态方法,但没有意识到第一个参数不是“ self”,因此默认情况下会发出警告。这种混乱是由编程语言设计引起的。我建议您遵循编程设计(即使它似乎不是一个好的模式),添加“ staticmethod”,以免造成混淆。如果您添加“自我”完全没问题,那么如果您愿意也不要使用它。我所说的只是理解编程设计的另一种选择。
Junjun Wu
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.