新的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[谢谢@DavidPärsson]

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

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

为了支持OP的恐慌,建议您在任何可能的时候添加staticmethod,这违背了一个原则,即以后使代码的限制更少更容易,而不是使它更容易——使一个方法静态使它现在限制更少,因为您可以调用class.f()而不是instance.f()。

以下是这个警告存在的原因:

它宣传静态方法。它让开发人员意识到他们可能想要做的事情。 正如@JohnWorrall所指出的,当self无意中被排除在函数之外时,它会引起你的注意。 这是一个重新思考对象模型的线索;也许这个函数根本不属于这个类。


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

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

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


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


这可能有点乱,但有时你只是不需要访问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作为第一个参数传递。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作为方法参数传递。

理解了这一点,你就不需要任何变通办法了。


与其在特定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()