Por que o pycharm propõe alterar o método para estático


153

A nova versão do pycharm (3.1.3 community edition) propõe converter os métodos que não funcionam com o estado do objeto atual em estático.

insira a descrição da imagem aqui

Qual é a razão prática para isso? Algum tipo de otimização de micro-desempenho (ou memória)?


3
Você clicou em "mais ..."? Você faz referência a selfalgum lugar dentro do método? (Se a questão realmente é "por que os designers da PyCharm projetá-lo desta forma ... você vai ter que pedir-lhes, não tão ...)
Wooble

7
@ Wooble: existe return 1como uma única linha de implementação do método. "More" não contém nada útil
zerkms

Respostas:


188

O PyCharm "pensa" que você pode querer ter um método estático, mas esqueceu de declarar que é estático (usando o @staticmethoddecorador).

O PyCharm propõe isso porque o método não usa self em seu corpo e, portanto, na verdade não altera a instância da classe . Portanto, o método pode ser estático, ou seja, chamado sem passar uma instância de classe ou mesmo sem ter criado uma instância de classe.


4
Muitas pessoas responderam com essa resposta de sabor. Eu acrescentaria que, se você sabe que definitivamente não será um método estático, inclua um "throw NotImplementedError" enquanto estiver lá para ter certeza de que não o usará sem concluir.
Richard Green

1
Pode haver casos em que o aviso do PyCharm é injustificado, pois não queremos um método estático nem alteramos o estado. Por outro lado, se o método ainda não foi implementado, parece sempre uma boa ideia aumentar a NotImplementedError.
jolvi

3
Tenho o caso de que minha implementação padrão retorna uma constante, mas minhas subclasses têm permissão para retornar um valor, dependendo self. Nesse caso, o aviso é negligenciável e eu o marquei # noinspection PyMethodMayBeStatic. É uma pena que o IntelliJ IDEA não ofereça adicionar esse comentário desabilitante nos menus de contexto para esse aviso.
Alfe

Sugiro alterar a severidade dessa inspeção do PyCharm de "Aviso" para "Sem destaque, apenas corrigir" nas preferências do PyCharm. (É produzir muitos falsos positivos para mim.)
maciek

50

Concordado com @jolvi, @ArundasR e outros, o aviso ocorre em uma função de membro que não usa self.

Se você tem certeza de que o PyCharm está errado, que a função não deve ser a @staticmethod, e se você valorizar zero avisos, poderá fazer com que este desapareça de duas maneiras diferentes:

Solução nº 1

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

def is_not_used(self):
    pass

Solução nº 2 [Obrigado @ DavidPärsson ]

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

O aplicativo que eu tinha para isso (o motivo pelo qual não consegui usar o @staticmethod) foi criar uma tabela de funções do manipulador para responder a um campo de subtipo de protocolo. Todos os manipuladores tinham que ter a mesma forma de curso (estático ou não estático). Mas alguns não fizeram nada com a instância. Se eu fizesse essas estáticas, obteria o objeto "TypeError: 'staticmethod' não é possível chamar".

Para apoiar a consternação do OP, sugerir que você adicione método estático sempre que puder, contraria o princípio de que é mais fácil tornar o código menos restritivo posteriormente, do que torná-lo mais - tornar um método estático o torna menos restritivo agora, na medida em que você pode chame class.f () em vez de instance.f ().

Adivinha por que esse aviso existe:

  • Ele anuncia o método static . Isso torna os desenvolvedores conscientes de algo que eles podem ter pretendido.
  • Como aponta o @ JohnWorrall, chama sua atenção quando o eu foi inadvertidamente deixado de fora da função.
  • É uma sugestão para repensar o modelo de objeto; talvez a função não pertença a essa classe.

1
"tornar um método estático o torna menos restritivo agora" --- não o faz. Por exemplo: métodos polimórficos
zerkms 03/08

Penso que o último ponto merece ser repetido: "por que você o torna um método, quando é claramente uma função?" Mantenha o material que realmente precisa de uma instância separado do material estrutural que lida com algum aspecto. Você pode subdividi-lo facilmente em um módulo separado.
dhill

As regras do @dhill são lindas até o dia em que você pensa em uma exceção razoável. Eu descrevi um, uma lista de retornos de chamada.
21415 Bob Stein

7
A adição # noinspection PyMethodMayBeStaticacima do método ou classe suprime o aviso e, na minha opinião, é melhor do que chamar um método vazio.
David Pärsson

1
@Talha: selfnão é removido em Python3.
Junuxx 31/05/19

12

Eu acho que o motivo desse aviso é a configuração no Pycharm. Você pode desmarcar a seleção O método pode ser estático em Editor-> Inspeção


12
Minha pergunta era por que essa inspeção existe. Eu entendo que posso desligá-lo. Desculpe, não é uma resposta.
Zerkms

8

Eu concordo com as respostas dadas aqui (o método não usa selfe, portanto, pode ser decorado com @staticmethod).

Gostaria de acrescentar que você talvez queira mover o método para uma função de nível superior, em vez de um método estático dentro de uma classe. Para obter detalhes, consulte esta pergunta e a resposta aceita: python - devo usar métodos estáticos ou funções de nível superior

Mover o método para uma função de nível superior também corrigirá o aviso do PyCharm.


Resposta realmente útil - talvez o PyCharm deva renomear o aviso para 'método pode ser estático ou função de nível superior'. Ao refatorar um método, o pycharm criará uma função de nível superior e não um método estático, se selfnão for um parâmetro.
Suzana

@ tlo +1 por mencionar o decorador. Eu tenho uma classe com um método que não usa selfe, portanto, pode ser de nível superior, no entanto, isso não parece lógico quando se olha para o que esse método faz - como nível superior, ele pareceria mais um método global, enquanto é de fato, um pequeno método auxiliar para instâncias criadas a partir dessa classe. Portanto, para manter meu código logicamente organizado, o decorador é a solução perfeita.
kasimir

7

Eu posso imaginar as seguintes vantagens de ter um método de classe definido como estático:

  • você pode chamar o método apenas usando o nome da classe, sem necessidade de instanciar.

as vantagens restantes são provavelmente marginais, se presentes:

  • pode correr um pouco mais rápido
  • economize um pouco de memória

Sim. Mas o problema é - não estou usando como método estático. Caso contrário, já seria estático. Portanto, o PyCharm aconselha fazê-lo sem uma boa razão (?). "as vantagens restantes são provavelmente marginais, se presentes" --- sim, exatamente. Mas se for o caso - é um conselho bobo da PyCharm
zerkms

1
@zerkms é assim que se passa com alguns casos encantadores :-)
Jan Vlcinsky

1
Os métodos estáticos são inimigos da construção de um bom software. Eles anulam muitos princípios, de modo que a bitexecução mais rápida não é o ponto (porque eles rodam no RAM, portanto, é rápido nos dois casos) e, como você sabe, os computadores agora têm bunchmemória para que isso não seja mais um problema. Observe também o seu primeiro pensamento: esse é um comportamento processual, não orientado a objetos.
AmirHossein

4

Desde que você não se referia a selfno barcorpo do método, PyCharm está perguntando se você pode ter queria fazer barestática. Em outras linguagens de programação, como Java, existem razões óbvias para declarar um método estático. No Python, o único benefício real para um método estático (AFIK) é poder chamá-lo sem uma instância da classe. No entanto, se esse é o seu único motivo, provavelmente é melhor usar uma função de nível superior - como observado aqui .

Em suma, não tenho cem por cento de certeza por que está lá. Acho que eles provavelmente o removerão em um próximo lançamento.


3

Essa mensagem de erro me ajudou muito, pois eu não tinha percebido que havia escrito minha função acidentalmente usando meu exemplo de teste

my_player.attributes[item] 

em vez da maneira correta

self.attributes[item]

1

Pode ser um pouco confuso, mas às vezes você não precisa acessar self, mas prefere manter o método na classe e não torná-lo estático. Ou você só quer evitar adicionar um monte de decoradores desagradáveis. Aqui estão algumas soluções possíveis para essa situação.

Se o seu método tiver apenas efeitos colaterais e você não se importar com o que ele retorna:

def bar(self):
    doing_something_without_self()
    return self

Se você precisar do valor de retorno:

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

Agora seu método está sendo usado selfe o aviso desaparece!


0

A razão pela qual o Pycharm o torna um aviso, porque o Python se auto-passará como o primeiro argumento ao chamar um método estático none (não adicione @staticmethod). Pycharm sabe disso.

Exemplo:

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)

Eu sou de Java, no Java "self" é chamado "this", você não precisa escrever self (ou isso) como argumento no método de classe. Você pode simplesmente chamar a si mesmo conforme necessário dentro do método. Mas o Python "precisa" passar o self como argumento de método.

Ao entender isso, você não precisa de nenhuma solução alternativa como resposta do @BobStein.


Passa selfe daí?
zerkms 12/01

@zerkms '@staticmethod' não passa 'self'
Junyu Wu 13/01

Eu apenas citei você: "Python passará a si próprio como o primeiro argumento ... Pycharm sabe disso". E daí? Pycharm sabe disso, eu sei disso. Qual o motivo para marcar o método?
zerkms 15/01

@zerkms porque Pycharm acha que seu primeiro parâmetro de método pode não ser o "self". Normalmente, o ppl não cria um parâmetro de método e nunca o usa. O Pycharm pensa que você está criando um método estático e não percebeu que o primeiro parâmetro não é o "eu", portanto coloca um aviso por padrão. Essa confusão causada pelo design da linguagem de programação. Eu sugiro que você siga o design de programação (mesmo que não pareça um bom padrão), adicione "staticmethod", para evitar confusão. É muito bom se você adicionar um "eu" e nunca usá-lo, se preferir. O que digo é apenas uma opinião diferente ao entender o design de programação.
Junyu Wu 19/01
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.