问题:pycharm为什么建议将方法更改为静态
新的pycharm版本(3.1.3社区版)建议将不适用于当前对象状态的方法转换为静态方法。
实际的原因是什么?某种微性能(或内存)优化?
回答 0
PyCharm认为您可能想拥有一个静态方法,但是却忘记声明它是静态的(使用@staticmethod
装饰器)。
PyCharm提出这一点是因为该方法未在其主体中使用 self
,因此实际上并未更改类实例。因此,该方法可以是静态的,即可以在不传递类实例的情况下甚至在没有创建类实例的情况下调用。
回答 1
同意@ 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被无意中遗漏在函数之外时,它会引起您的注意。
- 重新思考对象模型是一个提示。函数可能根本不属于此类。
回答 2
我认为此警告的原因是在Pycharm中进行配置。您可以在编辑器->检查中取消选中选择方法可能是静态的
回答 3
我同意此处给出的答案(该方法未使用self
,因此可以用修饰@staticmethod
)。
我想补充一点,您可能想将方法移至顶级函数,而不是将类中的静态方法移至该函数。有关详细信息,请参见此问题和可接受的答案:python-我应该使用静态方法还是顶层函数
将方法移至顶层函数也将修复PyCharm警告。
回答 4
我可以想象将类方法定义为静态方法的以下优点:
- 您可以只使用类名调用该方法,而无需实例化它。
如果存在的话,其余的优势可能是微不足道的:
- 可能会跑得更快
- 节省一点内存
回答 5
由于您未self
在bar
方法主体中进行引用,因此PyCharm会询问您是否要使其bar
静态。在其他编程语言(如Java)中,显然有理由声明静态方法。在Python中,静态方法(AFIK)的唯一真正好处是无需类的实例即可调用它。但是,如果这是您的唯一原因,那么最好使用顶级功能-如此处所述。
简而言之,我不确定它为什么会在那里。我猜他们可能会在即将发布的版本中将其删除。
回答 6
此错误消息对我有很多帮助,因为我还没有意识到我不小心使用测试示例播放器来编写函数
my_player.attributes[item]
而不是正确的方法
self.attributes[item]
回答 7
可能有点混乱,但是有时候您不需要访问self
,但是您希望将方法保留在类中而不是使其静态。或者,您只想避免添加一堆难看的装饰器。以下是针对这种情况的一些可能的解决方法。
如果您的方法仅具有副作用,并且您不关心它返回的结果:
def bar(self):
doing_something_without_self()
return self
如果确实需要返回值:
def bar(self):
result = doing_something_without_self()
if self:
return result
现在您的方法正在使用self
,警告消失了!
回答 8
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答案。