É possível ter métodos estáticos em Python que eu poderia chamar sem inicializar uma classe, como:
ClassName.static_method()
fonte
É possível ter métodos estáticos em Python que eu poderia chamar sem inicializar uma classe, como:
ClassName.static_method()
Sim, usando o decorador staticmethod
class MyClass(object):
@staticmethod
def the_static_method(x):
print(x)
MyClass.the_static_method(2) # outputs 2
Observe que algum código pode usar o método antigo de definir um método estático, usando staticmethod
como uma função e não como um decorador. Isso só deve ser usado se você tiver que suportar versões antigas do Python (2.2 e 2.3)
class MyClass(object):
def the_static_method(x):
print(x)
the_static_method = staticmethod(the_static_method)
MyClass.the_static_method(2) # outputs 2
Isso é totalmente idêntico ao primeiro exemplo (usando @staticmethod
), mas não usando a sintaxe agradável do decorador
Finalmente, use staticmethod()
com moderação! Existem muito poucas situações em que métodos estáticos são necessários no Python, e eu os vi usados muitas vezes em que uma função separada de "nível superior" seria mais clara.
A seguir, é apresentado literalmente na documentação :
Um método estático não recebe um primeiro argumento implícito. Para declarar um método estático, use este idioma:
class C: @staticmethod def f(arg1, arg2, ...): ...
O formulário @staticmethod é um decorador de funções - consulte a descrição das definições de funções em Definições de funções para obter detalhes.
Pode ser chamado na classe (como
C.f()
) ou em uma instância (comoC().f()
). A instância é ignorada, exceto por sua classe.Os métodos estáticos no Python são semelhantes aos encontrados em Java ou C ++. Para um conceito mais avançado, consulte
classmethod()
.Para obter mais informações sobre métodos estáticos, consulte a documentação sobre a hierarquia de tipos padrão em A hierarquia de tipos padrão .
Novo na versão 2.2.
Alterado na versão 2.4: Sintaxe do decorador de funções adicionada.
@staticmethod
decoração ou usar um ponteiro de função, quando você pode simplesmente evitar o primeiroself
parâmetro? Bem, para um objetoa
, você não será capaz de chamadaa.your_static_method()
, o que é permitido em outros idiomas, mas é assim mesmo considerado uma má prática eo compilador sempre adverte sobre issoClassName.methodName()
se fosse um método estático e, em seguida, nenhumself
será fornecido ao método. Como você disse, ainda será possível também chamar esse método comoClassInstance.methodName()
eself
será fornecido como o primeiro parâmetro, independentemente do nome.Eu acho que Steven está realmente certo . Para responder à pergunta original, então, para configurar um método de classe, simplesmente assuma que o primeiro argumento não será uma instância de chamada e, em seguida, certifique-se de chamar o método apenas da classe.
(Observe que esta resposta se refere ao Python 3.x. No Python 2.x, você receberá um
TypeError
por chamar o método na própria classe.)Por exemplo:
Nesse código, o método "rollCall" assume que o primeiro argumento não é uma instância (como seria se fosse chamado por uma instância e não por uma classe). Desde que "rollCall" seja chamado da classe e não de uma instância, o código funcionará bem. Se tentarmos chamar "rollCall" de uma instância, por exemplo:
no entanto, faria com que uma exceção fosse lançada porque enviaria dois argumentos: ele próprio e -1, e "rollCall" é definido apenas para aceitar um argumento.
Aliás, rex.rollCall () enviaria o número correto de argumentos, mas também causaria uma exceção, porque agora n representaria uma instância Dog (ou seja, rex) quando a função espera que n seja numérico.
É aqui que entra a decoração: se precedermos o método "rollCall" com
então, declarando explicitamente que o método é estático, podemos chamá-lo de uma instância. Agora,
podia funcionar. A inserção de @staticmethod antes de uma definição de método impede que uma instância se envie como argumento.
Você pode verificar isso tentando o seguinte código com e sem a linha @staticmethod comentada.
fonte
TypeError: unbound method rollCall() must be called with Dog instance as first argument (got int instance instead)
T.my_static_method()
outype(my_t_instance).my_static_method()
, pois isso é mais claro e torna imediatamente óbvio que estou chamando um método estático.Sim, confira o decorador staticmethod :
fonte
Você realmente não precisa usar o
@staticmethod
decorador. Apenas declarando um método (que não espera o parâmetro self) e chamá-lo da classe O decorador está lá apenas no caso de você querer chamá-lo também de uma instância (que não era o que você queria fazer)Principalmente, você apenas usa funções ...
fonte
class Dummy: def static1(): print "hello from static1" @staticmethod def static2(): print "hello from static2" Dummy.static2() Dummy.static1()
Saída: hello from static2 Traceback <última chamada mais recente>: Arquivo "ll.py", linha 46, em <module> Dummy.static1 () TypeError: o método não estático static1 () deve ser chamado com instância manequim como primeiro argumento (não tem nada em seu lugar)self
como o primeiro argumento, a menos que você o diga. (ver: decorador)self
ref de forma apropriada, dependendo de como é chamado. Caso de teste: pastebin.com/12DDV7DB .staticmethod
decorador permite chamar a função na classe e em uma instância (essa solução falha ao chamar a função em uma instância).class C: def callme(): print('called'); C.callme()
Sim, métodos estáticos podem ser criados assim (embora seja um pouco mais Pythonic usar sublinhados em vez do CamelCase para métodos):
O exemplo acima usa a sintaxe do decorador. Essa sintaxe é equivalente a
Isso pode ser usado exatamente como você descreveu:
Um exemplo interno de um método estático está
str.maketrans()
no Python 3, que era uma função nostring
módulo do Python 2.Outra opção que pode ser usada como você descreve é
classmethod
: a diferença é que o método de classe obtém a classe como primeiro argumento implícito e, se for subclassificado, obtém a subclasse como primeiro argumento implícito.Observe que esse
cls
não é um nome obrigatório para o primeiro argumento, mas os codificadores Python mais experientes o considerarão mal feito se você usar qualquer outra coisa.Estes são normalmente usados como construtores alternativos.
Um exemplo embutido é
dict.fromkeys()
:fonte
Além das particularidades de como os objetos do método estático se comportam, há um certo tipo de beleza que você pode encontrar com eles quando se trata de organizar o código no nível do módulo.
...
...
...
Agora, torna-se um pouco mais intuitivo e auto-documentado no contexto em que certos componentes devem ser usados e é ideal para nomear casos de teste distintos, além de ter uma abordagem direta de como os módulos de teste são mapeados para módulos reais sob testes para puristas .
Costumo achar viável aplicar essa abordagem à organização do código de utilidade de um projeto. Muitas vezes, as pessoas imediatamente correm para criar um
utils
pacote e terminam com 9 módulos, dos quais um tem 120 LOC e o restante são duas dúzias de LOC, na melhor das hipóteses. Prefiro começar com isso e convertê-lo em um pacote e criar módulos apenas para os animais que realmente os merecem:fonte
Talvez a opção mais simples seja colocar essas funções fora da classe:
Usando esse método, as funções que modificam ou usam o estado interno do objeto (têm efeitos colaterais) podem ser mantidas na classe e as funções reutilizáveis do utilitário podem ser movidas para fora.
Digamos que esse arquivo seja chamado
dogs.py
. Para usá-los, você chamaria emdogs.barking_sound()
vez dedogs.Dog.barking_sound
.Se você realmente precisa de um método estático para fazer parte da classe, pode usar o decorador staticmethod .
fonte
Portanto, métodos estáticos são os métodos que podem ser chamados sem criar o objeto de uma classe. Por exemplo :-
No exemplo acima, o método
add
é chamado pelo nome da classe eA
não pelo nome do objeto.fonte
Os métodos estáticos do Python podem ser criados de duas maneiras.
Usando staticmethod ()
Resultado:
Resultado: 25
Usando @staticmethod
Resultado:
Resultado: 25
fonte
Encontro essa pergunta de tempos em tempos. O caso de uso e o exemplo de que gosto é:
Não faz sentido criar um objeto da classe cmath, porque não há estado em um objeto cmath. No entanto, cmath é uma coleção de métodos todos relacionados de alguma forma. No meu exemplo acima, todas as funções no cmath atuam em números complexos de alguma maneira.
fonte