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

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

在此处输入图片说明

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

The new pycharm release (3.1.3 community edition) proposes to convert the methods that don’t work with the current object’s state to static.

enter image description here

What is the practical reason for that? Some kind of micro-performance(-or-memory)-optimization?


回答 0

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

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

PyCharm “thinks” that you might have wanted to have a static method, but you forgot to declare it to be static (using the @staticmethod decorator).

PyCharm proposes this because the method does not use self in its body and hence does not actually change the class instance. Hence the method could be static, i.e. callable without passing a class instance or without even having created a class instance.


回答 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被无意中遗漏在函数之外时,它会引起您的注意。
  • 重新思考对象模型是一个提示。函数可能根本不属于此类。

Agreed with @jolvi, @ArundasR, and others, the warning happens on a member function that doesn’t use self.

If you’re sure PyCharm is wrong, that the function should not be a @staticmethod, and if you value zero warnings, you can make this one go away two different ways:

Workaround #1

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

def is_not_used(self):
    pass

Workaround #2 [Thanks @DavidPärsson]

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

The application I had for this (the reason I could not use @staticmethod) was in making a table of handler functions for responding to a protocol subtype field. All handlers had to be the same form of course (static or nonstatic). But some didn’t happen to do anything with the instance. If I made those static I’d get “TypeError: ‘staticmethod’ object is not callable”.

In support of the OP’s consternation, suggesting you add staticmethod whenever you can, goes against the principle that it’s easier to make code less restrictive later, than to make it more — making a method static makes it less restrictive now, in that you can call class.f() instead of instance.f().

Guesses as to why this warning exists:

  • It advertises staticmethod. It makes developers aware of something they may well have intended.
  • As @JohnWorrall’s points out, it gets your attention when self was inadvertently left out of the function.
  • It’s a cue to rethink the object model; maybe the function does not belong in this class at all.

回答 2

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

I think that the reason for this warning is config in Pycharm. You can uncheck the selection Method may be static in Editor->Inspection


回答 3

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

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

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

I agree with the answers given here (method does not use self and therefore could be decorated with @staticmethod).

I’d like to add that you maybe want to move the method to a top-level function instead of a static method inside a class. For details see this question and the accepted answer: python – should I use static methods or top-level functions

Moving the method to a top-level function will fix the PyCharm warning, too.


回答 4

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

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

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

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

I can imagine following advantages of having a class method defined as static one:

  • you can call the method just using class name, no need to instantiate it.

remaining advantages are probably marginal if present at all:

  • might run a bit faster
  • save a bit of memory

回答 5

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

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

Since you didn’t refer to self in the bar method body, PyCharm is asking if you might have wanted to make bar static. In other programming languages, like Java, there are obvious reasons for declaring a static method. In Python, the only real benefit to a static method (AFIK) is being able to call it without an instance of the class. However, if that’s your only reason, you’re probably better off going with a top-level function – as note here.

In short, I’m not one hundred percent sure why it’s there. I’m guessing they’ll probably remove it in an upcoming release.


回答 6

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

my_player.attributes[item] 

而不是正确的方法

self.attributes[item]

This error message just helped me a bunch, as I hadn’t realized that I’d accidentally written my function using my testing example player

my_player.attributes[item] 

instead of the correct way

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,警告消失了!

It might be a bit messy, but sometimes you just don’t need to access self, but you would prefer to keep the method in the class and not make it static. Or you just want to avoid adding a bunch of unsightly decorators. Here are some potential workarounds for that situation.

If your method only has side effects and you don’t care about what it returns:

def bar(self):
    doing_something_without_self()
    return self

If you do need the return value:

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

Now your method is using self, and the warning goes away!


回答 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答案。

The reason why Pycharm make it as a warning because Python will pass self as the first argument when calling a none static method (not add @staticmethod). Pycharm knows it.

Example:

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)

I’m from Java, in Java “self” is called “this”, you don’t need write self(or this) as argument in class method. You can just call self as you need inside the method. But Python “has to” pass self as a method argument.

By understanding this you don’t need any Workaround as @BobStein answer.


声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。