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

Python 为什么pycharm建议将方法更改为静态,python,pycharm,Python,Pycharm,新的pycharm版本(3.1.3社区版)建议将不适用于当前对象状态的方法转换为静态方法 实际原因是什么?某种微性能(或内存)优化?我可以想象将类方法定义为静态类方法的以下优点: 只需使用类名即可调用该方法,无需实例化 剩下的优势如果存在的话可能是微不足道的: 可能会跑快一点 节省一点内存 PyCharm“认为”您可能想要一个静态方法,但您忘记了将其声明为静态(使用@staticmethod装饰器) PyCharm提出这一点是因为该方法在其主体中不使用self,因此实际上不会更改类实例。

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


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

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

  • 只需使用类名即可调用该方法,无需实例化
剩下的优势如果存在的话可能是微不足道的:

  • 可能会跑快一点
  • 节省一点内存
PyCharm“认为”您可能想要一个静态方法,但您忘记了将其声明为静态(使用
@staticmethod
装饰器)


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

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

my_player.attributes[item] 
而不是正确的方法

self.attributes[item]

由于您没有在
bar
方法主体中引用
self
,PyCharm询问您是否希望将
bar
设置为静态。在其他编程语言(如Java)中,声明静态方法有明显的原因。在Python中,静态方法(AFIK)唯一真正的好处是能够在没有类实例的情况下调用它。然而,如果这是您唯一的原因,那么您最好使用顶级函数——请注意


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

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

如果您确定PyCharm是错误的,那么该函数不应该是一个
@staticmethod
,如果您将警告值设为零,则可以通过两种不同的方式消除此警告:

解决办法#1

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

def is_not_used(self):
    pass
解决方法#2[谢谢]

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


为了支持OP的惊愕,建议您尽可能地添加staticmethod,这与以下观点背道而驰:以后使代码的限制性降低要比使代码的限制性提高容易——现在使方法成为静态会使其限制性降低,因为您可以调用class.f()而不是instance.f()

猜测此警告存在的原因:

  • 宣传静态方法。它让开发人员意识到他们可能想要的东西
  • 正如@johnworll's所指出的,当self无意中被忽略时,它会引起你的注意
  • 这是重新思考对象模型的提示;可能函数根本不属于这个类

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

我想补充一点,您可能希望将该方法移动到顶级函数,而不是类中的静态方法。有关详细信息,请参见此问题和公认的答案:


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

我认为出现此警告的原因是PyCharm中的配置。
您可以在编辑器->检查中取消选中selection方法可能是静态的,这可能有点混乱,但有时您不需要访问self,但您希望将该方法保留在类中,而不是使其静态。或者你只是想避免添加一堆难看的装饰。以下是针对这种情况的一些潜在解决方法

如果您的方法只有副作用,而您不关心它返回的结果:

def bar(self):
    doing_something_without_self()
    return self
如果确实需要返回值:

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

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

Pycharm之所以将其作为警告,是因为Python在调用非静态方法(而不是add@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)
T类:
def test():
打印“我是一个正常的方法!”
t=t()
t、 测试()
输出:
回溯(最近一次呼叫最后一次):
文件“F:/Workspace/test\u script/test.py”,第28行,在
T().test()
TypeError:test()不接受任何参数(给定1个)
我来自Java,在Java中“self”被称为“this”,您不需要将write self(或this)作为类方法中的参数。您可以根据需要在方法内部调用self。但是Python“必须”将self作为方法参数传递


通过理解这一点,您不需要像@BobStein answer那样进行任何变通。

而不是在特定的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()
类动物:
定义初始化(自):
印刷品(“动物创造”)
def eat(self):

不是赛尔夫,是的。但问题是,我不是把它当作静态方法来使用。否则它就已经是静态的了。因此,PyCharm建议在没有充分理由的情况下这样做(?)。“剩下的优势如果存在的话可能是微不足道的”——是的,没错。但如果是这样的话,这是一个愚蠢的建议PyCharm@zerkms以下是一些迷人的例子的情况:-)静态方法是构建好软件的敌人。它们使许多原则无效,因此
的运行速度不会更快
class Animal:
    def __init__(self):
        print("Animal created")

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


my_animal = Animal()