Métodos estáticos - como chamar um método de outro método?

95

Quando tenho métodos regulares para chamar outro método em uma classe, tenho que fazer isso

class test:
    def __init__(self):
        pass
    def dosomething(self):
        print "do something"
        self.dosomethingelse()
    def dosomethingelse(self):
        print "do something else"

mas quando tenho métodos estáticos, não consigo escrever

self.dosomethingelse()

porque não há instância. Como devo fazer em Python para chamar um método estático de outro método estático da mesma classe?

Edit: que bagunça. Ok, editei de volta a pergunta para a pergunta original. Já tenho a resposta para a segunda pergunta que está no comentário de Peter Hansen. Se você acha que eu deveria abrir outra pergunta para uma resposta que já tenho, por favor me diga.

Pablo
fonte
3
@pablo: você não pode mudar a essência da pergunta !! Encerre esta questão e comece outra !!
jldupont
ok ok você quer dizer deletar a pergunta? A resposta já está lá no comentário de Peter Hansen
Pablo
@pablo: você não pode deletar aqui isso não seria educado para todos que contribuíram com respostas para sua pergunta. Você precisa aceitar uma resposta e criar uma nova pergunta.
jldupont
1
@pablo: e só para deixar claro: uma resposta deve ser aceita para a formulação original da sua pergunta. Não se preocupe, você aprenderá a se virar por aqui. Saúde :-)
jldupont

Respostas:

77

class.method Deveria trabalhar.

class SomeClass:
  @classmethod
  def some_class_method(cls):
    pass

  @staticmethod
  def some_static_method():
    pass

SomeClass.some_class_method()
SomeClass.some_static_method()
jldupont
fonte
16
Um conselho deve ser adicionado aqui: é claro que os métodos de classe não têm desvantagens sobre os métodos estáticos, e os métodos de classe permitem que o método seja estendido no futuro para chamar outros métodos de classe. Portanto, deve ser sempre preferido, mesmo que não haja necessidade imediata.
u0b34a0f6ae
1
@ u0b34a0f6ae: Não sei se estou fazendo algo bom ou não ... mas defini um decorador dentro de uma classe. O decorador deve ser um "método estático", não um "método de classe".
André Caldas
@ u0b34a0f6ae Os métodos de classe são sempre seguros para threads? Em meu caso de uso, estou usando métodos estáticos em threads para evitar acesso acidental à classe que pode não ser segura para threads.
aquavitae
@ u0b34a0f6ae sempre é um pouco forte. Por exemplo, os métodos estáticos do PySpark podem ser usados ​​em jobs rdd e os métodos de classe não.
Laurens Koppenol
134

Como devo fazer em Python para chamar um método estático de outro método estático da mesma classe?

class Test() :
    @staticmethod
    def static_method_to_call()
        pass

    @staticmethod
    def another_static_method() :
        Test.static_method_to_call()

    @classmethod
    def another_class_method(cls) :
        cls.static_method_to_call()
Warvariuc
fonte
A chamada Test.static_method_to_call()deve funcionar a partir de outros métodos não estáticos e não de classe desta classe também, certo? (... e provavelmente outras aulas também?)
gr4nt3d
Sim, Test.static_method_to_call()funcionará em qualquer lugar.
warvariuc
11

NOTA - parece que a pergunta mudou um pouco. A resposta à questão de como você chama um método de instância a partir de um método estático é que você não pode sem passar uma instância como um argumento ou instanciar essa instância dentro do método estático.

O que se segue é principalmente para responder "como você chama um método estático de outro método estático":

Tenha em mente que não é uma diferença entre métodos estáticos e métodos de classe em Python. Um método estático não leva nenhum primeiro argumento implícito, enquanto um método de classe leva a classe como o primeiro argumento implícito (geralmente clspor convenção). Com isso em mente, veja como você faria isso:

Se for um método estático:

test.dosomethingelse()

Se for um método de classe:

cls.dosomethingelse()
Jason Baker
fonte
1
você só pode usar cls.dosomethingelse()de dentro da definição de classe.
jldupont
3
Para ser mais preciso, você só pode usar cls.dosomethingelse()o método de classe em si. Assim como você só pode usar selfde dentro de um método de instância.
Jason Baker
1
desculpe, eu escrevi a pergunta incorretamente. OOPS !. Eu queria escrever "Como devo fazer em Python para chamar um método de instância de outro método estático da mesma classe" e não "Como devo fazer em Python para chamar um método estático de outro método estático do mesmo classe "
Pablo
@pablo: Neste caso, você precisa escrever outra pergunta e terminar esta.
jldupont
@jldupont, já tenho a resposta, mas em um comentário. O que devo fazer porque não posso aceitar, mas seria um desperdício apagar a pergunta, não seria?
Pablo
4

OK, a principal diferença entre métodos de classe e métodos estáticos é:

  • O método de classe tem sua própria identidade, é por isso que eles devem ser chamados de dentro de uma INSTÂNCIA.
  • por outro lado, o método estático pode ser compartilhado entre várias instâncias, de modo que deve ser chamado de dentro da CLASSE
Ahmad Dwaik
fonte
0

você não pode chamar métodos não estáticos a partir de métodos estáticos, mas criando uma instância dentro do método estático .... deve funcionar assim

class test2(object):
    def __init__(self):
        pass

    @staticmethod
    def dosomething():
        print "do something"
        #creating an instance to be able to call dosomethingelse(),or you may use any existing instace
        a=test2()
        a.dosomethingelse()

    def dosomethingelse(self):
        print "do something else"

test2.dosomething()

espero que ajude você :)

Ahmad Dwaik
fonte
3
IMO, esta abordagem é notavelmente pior do que apenas usar @classmethodpara declarar seus métodos, e usar cls.dosomethingelse()dentro cls.dosomething()- pior em termos de desempenho (instanciar objetos apenas para obter acesso a um método estático) e legibilidade (não é simples, e imagino que esse tipo de de padrão tornou-se clichê, a base de código inteira pode se tornar bastante difícil para um mero humano analisar)
Kyle Wild,
Como li em outro lugar no SO, em vez de inicializar a instância diretamente para chamar um método, você pode apenas chamá-lo - ele se inicializará por conta própria.
Nakilon
0

Se eles não dependem da classe ou instância, por que não torná-los apenas uma função? Pois esta parece ser a solução óbvia. A menos, é claro, que você ache que será necessário sobrescrever, criar uma subclasse etc. Nesse caso, as respostas anteriores são a melhor aposta. Dedos cruzados Eu não vou ficar marcado apenas por oferecer uma solução alternativa que pode ou não atender às necessidades de alguém;).

Como a resposta correta dependerá do caso de uso do código em questão;) Aproveite

AppHandwerker
fonte