Statik yöntemler - Başka bir yöntemden bir yöntem nasıl çağrılır?


100

Bir sınıfta başka bir yöntemi çağırmak için normal yöntemlerim olduğunda, bunu yapmalıyım

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

ama statik yöntemlerim olduğunda yazamıyorum

self.dosomethingelse()

çünkü örnek yok. Python'da aynı sınıfın başka bir statik yönteminden statik bir yöntemi çağırmak için nasıl yapmalıyım?

Düzenleme: ne dağınıklık. Tamam, soruyu orijinal soruya geri düzenledim. Peter Hansen'ın yorumunda bulunan ikinci sorunun cevabını zaten buldum. Zaten sahip olduğum bir cevap için başka bir soru açmam gerektiğini düşünüyorsanız, lütfen bana söyleyin.


3
@pablo: Sorunun özünü değiştiremezsiniz !! Bu soruyu bitirin ve başka bir soruya başlayın !!
jldupont

tamam tamam soruyu silmek mi demek istiyorsun? Cevap Peter Hansen'ın yorumunda zaten var
Pablo

@pablo: Sorunuzun yanıtlarına katkıda bulunan herkes için nazik olmayacak olan burayı silemezsiniz. Bir cevabı kabul etmeniz ve yeni bir soru oluşturmanız gerekir .
jldupont

1
@pablo: ve açık olmak gerekirse: orijinal soru formülasyonunuz için bir cevap kabul edilmelidir . Endişelenme, burada yolunu öğreneceksin. Cheers :-)
jldupont

Yanıtlar:


80

class.method çalışmalı.

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

  @staticmethod
  def some_static_method():
    pass

SomeClass.some_class_method()
SomeClass.some_static_method()

17
Buraya tavsiye eklenmelidir: Sınıf yöntemlerinin statik yöntemlere göre hiçbir sakıncası olmadığı açıktır ve sınıf yöntemleri, yöntemin gelecekte diğer sınıf yöntemlerini çağırmak için genişletilmesine izin verir. Bu nedenle acil ihtiyaç olmasa da her zaman tercih edilmelidir.
u0b34a0f6ae

1
@ u0b34a0f6ae: İyi bir şey yapıp yapmadığımı bilmiyorum ... ama bir sınıf içinde bir dekoratör tanımladım. Dekoratörün bir "sınıf yöntemi" değil, "statik yöntem" olması gerekiyordu.
André Caldas

@ u0b34a0f6ae Yine de sınıf yöntemleri her zaman iş parçacığı güvenli midir? Kullanım durumumda, iş parçacığı açısından güvenli olmayabilecek sınıfa yanlışlıkla erişimi önlemek için iş parçacıklarında statik yöntemler kullanıyorum.
aquavitae

@ u0b34a0f6ae her zaman biraz güçlüdür. Örneğin PySpark statik yöntemlerini kullanmak rdd işlerinde kullanılabilir ve sınıf yöntemleri kullanılamaz.
Laurens Koppenol

143

Python'da aynı sınıfın başka bir statik yönteminden statik bir yöntemi çağırmak için nasıl yapmalıyım?

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()

Çağrı Test.static_method_to_call(), bu sınıfın diğer statik olmayan ve sınıf dışı yöntemlerinden de çalışmalıdır, değil mi? (... ve muhtemelen diğer sınıflar da?)
gr4nt3d

Evet, Test.static_method_to_call()her yerden çalışacak.
warvariuc

11

NOT - soru biraz değişmiş gibi görünüyor. Statik bir yöntemden bir örnek yöntemini nasıl çağıracağınız sorusunun yanıtı, bir örneği bağımsız değişken olarak geçirmeden veya bu örneği statik yöntem içinde başlatmadan yapamayacağınızdır.

Aşağıdakiler çoğunlukla "başka bir statik yöntemden statik bir yöntemi nasıl çağırırsınız" yanıtını vermektir:

Akılda Ayı oradaki olduğunu Python statik yöntemleri ve sınıf yöntemleri arasında bir fark vardır. Statik bir yöntem örtük ilk bağımsız değişken almazken, bir sınıf yöntemi sınıfı örtük ilk bağımsız değişken olarak alır (genellikle clskural gereği). Bunu göz önünde bulundurarak, işte bunu nasıl yapacağınız:

Statik bir yöntemse:

test.dosomethingelse()

Bir sınıf yöntemi ise:

cls.dosomethingelse()

1
yalnızca cls.dosomethingelse()sınıf tanımının içinden kullanabilirsiniz .
jldupont

3
Daha doğru olmak gerekirse, yalnızca cls.dosomethingelse()sınıf yönteminin içinden kullanabilirsiniz . Tıpkı yalnızca selfbir örnek yönteminin içinden kullanabileceğiniz gibi .
Jason Baker

1
üzgünüm, soruyu yanlış yazdım. OOPS !. "Aynı sınıfın başka bir statik yönteminden bir örnek yöntemini çağırmak için Python'da nasıl yapmalıyım?" sınıf "
Pablo

@pablo: Bu durumda başka bir soru yazıp bunu bitirmeniz gerekiyor .
jldupont

@jldupont, cevabım zaten var ama bir yorumda. Kabul edemediğim için ne yapmalıyım ama soruyu silmek israf olur, değil mi?
Pablo

4

Tamam, sınıf yöntemleri ile statik yöntemler arasındaki temel fark şudur:

  • sınıf yönteminin kendi kimliği vardır, bu yüzden bir INSTANCE içinden çağrılmaları gerekir.
  • Öte yandan statik yöntem, birden fazla örnek arasında paylaşılabilir, böylece SINIF içinden çağrılması gerekir.

Bu doğru görünmüyor - ancak buradaki anlam örnek olmadan belirsizdir, bu yüzden söylemek zor. Temel olarak, "sınıf yöntemleri" "bir örnek içinden" çağrılmak zorunda değildir ... MyClass.class_method()bildiği herhangi bir yerden çağrı yapabilirsiniz MyClass(belki "örnek yöntemlerini" düşünüyordunuz?)
mltsy

1

Bunlar sınıfa veya örneğe bağlı değilse neden onları bir işlev haline getirmiyorsunuz? Bu bariz bir çözüm gibi görünebilir. Elbette, üzerine yazılması gerektiğini düşünmüyorsanız, alt sınıf vb. Eğer öyleyse, o zaman önceki cevaplar en iyi bahistir. Parmaklar çaprazlanmış, sadece birinin ihtiyaçlarına uyan ya da uymayan alternatif bir çözüm önerdiğim için işaretlenmeyeceğim;).

Doğru cevap, söz konusu kodun kullanım durumuna bağlı olacağından;) Keyfini çıkarın


0

Statik yöntemlerden statik olmayan yöntemleri çağıramazsınız, ancak statik yöntemin içinde bir örnek oluşturarak .... böyle çalışmalıdır

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()

umarım bu sana yardımcı olur :)


3
IMO bu yaklaşım, yalnızca @classmethodyöntemlerinizi bildirmek için kullanmaktan ve cls.dosomethingelse()içinde kullanmaktan cls.dosomething()daha kötüdür - hem performans (yalnızca statik bir yönteme erişmek için nesneleri örnekleme) hem de okunabilirlik (bu basit değildir ve bu türden olup olmadığını tahmin ediyorum) modelin tamamı standart hale geldi, kod tabanının tamamı yalnızca bir insan için ayrıştırılması oldukça zor olabilir)
Kyle Wild

SO'da başka bir yerde okuduğum için, örneği doğrudan bir yöntemi çağırmak için başlatmak yerine, onu çağırabilirsiniz - kendi kendine başlatacaktır.
Nakilon
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.