为啥pycharm建议将方法更改为静态
Posted
技术标签:
【中文标题】为啥pycharm建议将方法更改为静态【英文标题】:Why does PyCharm propose to change method to static?为什么pycharm建议将方法更改为静态 【发布时间】:2014-06-26 14:50:55 【问题描述】:新的pycharm 版本(3.1.3 社区版)提出将不能处理当前对象状态的方法转换为静态。
这样做的实际原因是什么?某种微性能(或内存)优化?
【问题讨论】:
@Wooble:有return 1
作为该方法的单行实现。 “更多”不包含任何有用的内容
【参考方案1】:
我可以想象将类方法定义为静态方法的以下优点:
可以只使用类名调用方法,无需实例化。如果存在的话,剩余的优势可能是微不足道的:
可能会跑得快一点 节省一点内存【讨论】:
是的。但问题是 - 我没有将它用作静态方法。否则它已经是静态的了。所以 PyCharm 建议不要有充分的理由这样做(?)。 “如果存在的话,剩余的优势可能是微不足道的”——是的,确切地说。但如果是这样的话——这是 PyCharm 的一个愚蠢的建议 @zerkms 这就是它与一些迷人实例的搭配方式:-) 静态方法是构建优秀软件的敌人。它们使许多原则无效,因此bit
运行得更快并不是重点(因为它们在 ram 中运行,所以在这两种情况下都很快),而且您知道计算机现在有 bunch
的内存,所以这不再是问题了。另请注意您的第一个想法:这是一种程序行为,而不是面向对象的行为。【参考方案2】:
PyCharm“认为”您可能想要拥有一个静态方法,但您忘记将其声明为静态(使用@staticmethod
装饰器)。
PyCharm 提出这一点是因为该方法在其主体中没有使用self
,因此实际上并没有更改类实例。因此,该方法可以是静态的,即无需传递类实例或什至无需创建类实例即可调用。
【讨论】:
这么多人回答了这种风味反应。不过,我要补充一点,如果您知道它绝对不是静态方法,那么在您在那里时包含一个“抛出 NotImplementedError”,以确保您在没有完成它的情况下不会使用它。 在某些情况下,PyCharm 的警告可能是不合理的,因为我们既不需要静态方法也不需要更改状态。另一方面,如果该方法尚未实现,提出NotImplementedError
似乎总是一个好主意。
我的默认实现返回一个常量,但允许我的子类返回一个取决于self
的值。在这种情况下,警告是可以忽略的,我用# noinspection PyMethodMayBeStatic
标记它。遗憾的是,IntelliJ IDEA 不提供在此警告的上下文菜单中添加此禁用注释。
我建议在 PyCharm 的首选项中将此 PyCharm 检查的严重性从“警告”更改为“不突出显示,仅修复”。 (它给我带来了很多误报。)【参考方案3】:
这个错误消息对我有很大帮助,因为我没有意识到我不小心使用我的测试示例播放器编写了我的函数
my_player.attributes[item]
而不是正确的方式
self.attributes[item]
【讨论】:
【参考方案4】:由于您没有在 bar
方法主体中引用 self
,PyCharm 会询问您是否可能想要将 bar
设为静态。在其他编程语言(如 Java)中,声明静态方法的原因很明显。在 Python 中,静态方法 (AFIK) 的唯一真正好处是能够在没有类实例的情况下调用它。但是,如果这是您唯一的原因,那么您最好使用***函数 - 如注释 here。
简而言之,我不能百分百确定它为什么会出现。我猜他们可能会在即将发布的版本中删除它。
【讨论】:
【参考方案5】:同意@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' object is not callable”。
为了支持 OP 的惊愕,建议您尽可能添加 staticmethod,这与 principle 背道而驰,因为您可以调用 class.f() 而不是 instance.f()。
猜测为什么会出现这个警告:
它宣传静态方法。它让开发者意识到他们可能有过的意图。 正如@JohnWorrall 所指出的,当 self 无意中被忽略时,它会引起您的注意。 这是重新考虑对象模型的提示;也许函数根本不属于这个类。【讨论】:
“将方法设为静态可以减少现在的限制” --- 它根本没有。例如:多态方法 我认为最后一点值得重复:“你为什么要把它变成一个方法,而它显然是一个函数?”将真正需要实例的内容与处理某些方面的结构性内容分开。然后,您可以轻松地将其细分为单独的模块。 在方法或类上方添加# noinspection PyMethodMayBeStatic
会抑制警告,在我看来比调用空方法更好。
@Talha: self
在 Python3 中根本没有被删除。
@Talha,我不明白你的意思。我想不出 Python 2 中的 self
在 Python 3 中不需要的任何方式。你能举个例子或链接吗?【参考方案6】:
我同意这里给出的答案(方法不使用self
,因此可以用@staticmethod
装饰)。
我想补充一点,您可能希望将该方法移动到***函数,而不是类中的静态方法。有关详细信息,请参阅此问题和接受的答案:python - should I use static methods or top-level functions
将方法移动到***函数也将修复 PyCharm 警告。
【讨论】:
非常有用的答案 - 也许 PyCharm 应该将警告重命名为“方法可能是静态或***函数”。重构方法时,如果self
不是参数,pycharm 将创建一个***函数而不是静态方法。
@tlo +1 用于提及装饰器。我有一个类,其方法不使用self
,因此可能是***的,但是,在查看此方法的作用时,这并不合乎逻辑-因为***它看起来更像是一种全局方法,虽然它实际上是从该类创建的实例的一个小帮助方法。所以为了让我的代码在逻辑上井井有条,装饰器是完美的解决方案。【参考方案7】:
我认为这个警告的原因是 Pycharm 中的配置。 您可以在 Editor->Inspection
中取消选中 Method may be static【讨论】:
我的问题是为什么会存在这样的检查。我知道我可以关掉它。抱歉,没有答案。 不是问题的答案,但非常有用,谢谢!【参考方案8】:这可能有点混乱,但有时您只是不需要访问self
,但您更愿意将方法保留在类中并且不使其成为静态的。或者你只是想避免添加一堆难看的装饰器。以下是针对这种情况的一些潜在解决方法。
如果你的方法只有副作用,而你并不关心它返回什么:
def bar(self):
doing_something_without_self()
return self
如果确实需要返回值:
def bar(self):
result = doing_something_without_self()
if self:
return result
现在你的方法使用self
,警告消失了!
【讨论】:
我建议不要这样做。为什么要让您的代码更加混乱和混乱,只是为了让特定 IDE 的警告消失?这只是一个警告,让您查看它。如果它不是最好的解决方案,你不必按照它所说的去做。 IDE 并不总是知道什么最适合您的代码。【参考方案9】: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 认为您正在创建一个静态方法并且没有意识到第一个参数不是“自我”,因此默认情况下会发出警告。这种混乱是由编程语言设计引起的。我建议你按照程序设计(即使它看起来不是一个好的模式),添加“静态方法”,以避免混淆。如果你添加一个“自我”完全没问题,如果你愿意,就永远不要使用它。我说的只是理解程序设计的另一种选择。【参考方案10】:
与其在特定 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()
【讨论】:
我的问题是关于这个建议背后的基本原理,而不是解决方法。 知道了。想知道这是否可以向解释器发出信号,表明这不是静态方法。以上是关于为啥pycharm建议将方法更改为静态的主要内容,如果未能解决你的问题,请参考以下文章
Pycharm将venv python从3.6更改为3.7,而无需从头开始创建新环境[重复]
python 将PyCharm社区Python控制台更改为PyCharm Professional Django控制台(Django Shell)