Pycharm neden yöntemi statik olarak değiştirmeyi öneriyor?


163

Yeni pycharm sürümü (3.1.3 topluluk sürümü), mevcut nesnenin durumuyla çalışmayan yöntemleri statik hale dönüştürmeyi önerir.

görüntü açıklamasını buraya girin

Bunun pratik nedeni nedir? Bir çeşit mikro performans (-ya da-hafıza) -optimizasyon?


3
"Diğer ..." seçeneğini tıkladınız mı? selfYöntemin içinde herhangi bir yere referans veriyor musunuz ? (Soru gerçekten "PyCharm tasarımcıları bunu neden bu şekilde tasarladılarsa ... Onlara sormanız gerekecek, SO değil ...)
Wooble

7
@ Wooble: Yöntemin return 1tek satırlık uygulaması var. "Daha fazla" yararlı hiçbir şey içermiyor
zerkms

Yanıtlar:


205

PyCharm , statik bir yönteme sahip olmak istemiş olabileceğinizi "düşünüyor" , ancak siz bunun statik olduğunu bildirmeyi unuttunuz ( @staticmethoddekoratör kullanarak ).

PyCharm bunu önerir çünkü yöntem kendi gövdesinde kullanmaz self ve dolayısıyla sınıf örneğini gerçekten değiştirmez . Dolayısıyla yöntem statik olabilir, yani bir sınıf örneğini geçmeden veya bir sınıf örneği oluşturmadan çağrılabilir.


4
Pek çok insan bu lezzet cevabıyla cevap verdi. Yine de ekleyeceğim, bunun kesinlikle statik bir yöntem olmayacağını biliyorsanız, tamamlamadan kullanmayacağınızdan emin olmak için oradayken bir "throw NotImplementedError" ekleyin.
Richard Green

1
PyCharm'ın uyarısının haksız olduğu durumlar olabilir, çünkü ne statik bir yöntem istemiyoruz ne de durumu değiştiriyoruz. Öte yandan, yöntem henüz uygulanmadıysa, a'yı yükseltmek her zaman iyi bir fikir gibi görünmektedir NotImplementedError.
jolvi

3
Varsayılan uygulamamın bir sabit döndürdüğü bir durum var, ancak alt sınıflarımın bağlı olarak bir değer döndürmesine izin veriliyor self. Bu durumda uyarı ihmal edilebilir ve işaretliyorum # noinspection PyMethodMayBeStatic. IntelliJ IDEA'nın bu uyarının bağlam menülerine bu devre dışı bırakma açıklamasını eklemeyi teklif etmemesi ne yazık ki.
Alfe

PyCharm'ın tercihlerinde bu PyCharm incelemesinin ciddiyetini "Uyarı" dan "Vurgulama yok, sadece düzelt" olarak değiştirmenizi öneririm. (Benim için birçok yanlış pozitif üretiyor.)
maciek

53

@Jolvi, @ArundasR ve diğerleri ile anlaşmaya varıldığında, uyarı kullanmayan bir üye işlevinde gerçekleşir self.

PyCharm'ın yanlış olduğundan, işlevin a olmaması gerektiğinden @staticmethodeminseniz ve sıfır uyarıya değer veriyorsanız, bunu iki farklı yoldan kaldırabilirsiniz:

Geçici Çözüm 1

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

def is_not_used(self):
    pass

Çözüm 2 [Teşekkürler @ DavidPärsson ]

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

Bunun için sahip olduğum uygulama (@staticmethod'u kullanamamamın nedeni), bir protokol alt türü alanına yanıt vermek için bir eylemci işlevleri tablosu oluşturmaktı. Elbette tüm işleyiciler aynı biçimde olmalıdır (statik veya statik olmayan). Ancak bazıları örnekle hiçbir şey yapmadı. Bunları statik yaparsam, "TypeError: 'staticmethod' nesnesi çağrılabilir değil" alırdım.

OP'nin şaşkınlığını desteklemek için, yapabildiğiniz her zaman statik yöntem eklemenizi önermek, kodu daha fazla yapmaktan daha sonra daha az kısıtlayıcı hale getirmenin daha kolay olduğu ilkesine aykırıdır - bir yöntemi statik hale getirmek onu şimdi daha az kısıtlayıcı hale getirir. instance.f () yerine class.f () öğesini çağırın.

Bu uyarının neden var olduğunu tahmin eder:

  • Bu durukyöntem tanıtır . Geliştiricilerin, amaçladıkları bir şeyden haberdar olmalarını sağlar.
  • @ JohnWorrall'un belirttiği gibi, benlik yanlışlıkla işlevin dışında bırakıldığında dikkatinizi çeker .
  • Nesne modelini yeniden düşünmenin bir işaretidir; belki işlev bu sınıfa ait değildir .

1
"Bir yöntemi statik hale getirmek, onu şimdi daha az kısıtlayıcı hale getirir" --- hiç de öyle değil. Ör: polimorfik yöntemler
zerkms

Sanırım son nokta, "açıkça bir işlev varken neden onu bir yöntem haline getiriyorsunuz?" Bir örneğe gerçekten ihtiyaç duyan şeyleri, bazı yönlerle ilgilenen yapısal şeylerden ayrı tutun. Daha sonra bunu kolayca ayrı bir modüle bölebilirsiniz.
dhill

@dhill Kuralları, makul bir istisna düşündüğünüz güne kadar güzel şeylerdir. Bir geri arama listesi tarif ettim.
Bob Stein

7
# noinspection PyMethodMayBeStaticYöntemin veya sınıfın üstüne eklemek uyarıyı bastırır ve bence boş bir yöntemi çağırmaktan daha iyidir.
David Pärsson

1
@Talha: Python3'te selfhiç kaldırılmaz.
Junuxx

12

Sanırım bu uyarının nedeni Pycharm'da yapılandırma. Seçimin işaretini kaldırabilirsiniz Yöntem Düzenleyici-> İnceleme'de statik olabilir


12
Sorum, neden böyle bir denetimin var olduğuydu. Anladığım kadarıyla kapatabilirim. Üzgünüm, cevap değil.
zerkms

9

Burada verilen cevaplara katılıyorum (yöntem kullanılmaz selfve bu nedenle süslenebilir @staticmethod).

Yöntemi bir sınıf içinde statik bir yöntem yerine üst düzey bir işleve taşımak isteyebileceğinizi de eklemek isterim. Ayrıntılar için şu soruya ve kabul edilen yanıta bakın: python - statik yöntemler veya üst düzey işlevleri kullanmalı mıyım

Yöntemi üst düzey bir işleve taşımak PyCharm uyarısını da düzeltecektir.


Gerçekten yararlı cevap - belki PyCharm uyarıyı 'yöntem statik veya üst düzey işlev olabilir' olarak yeniden adlandırmalıdır. Bir yöntemi yeniden düzenlerken pycharm, selfbir parametre değilse zaten statik bir yöntem değil, üst düzey bir işlev oluşturacaktır .
Suzana

@tlo +1 dekoratörden bahsettiği için. Kullanmayan selfve bu nedenle üst düzey olabilecek bir yönteme sahip bir sınıfım var , ancak bu yöntemin ne yaptığına bakıldığında bu mantıklı gelmiyor - üst düzey olarak daha çok küresel bir yöntem gibi görünecek, aslında bu sınıftan oluşturulan örnekler için küçük bir yardımcı yöntem. Bu nedenle, kodumu mantıksal olarak organize etmek için dekoratör mükemmel bir çözümdür.
kasimir

7

Statik olarak tanımlanan bir sınıf yöntemine sahip olmanın aşağıdaki avantajlarını hayal edebiliyorum:

  • yöntemi yalnızca sınıf adını kullanarak çağırabilirsiniz, onu somutlaştırmanıza gerek yoktur.

Kalan avantajlar, eğer mevcutsa muhtemelen marjinaldir:

  • biraz daha hızlı koşabilir
  • biraz hafıza kaydet

Evet. Ama mesele şu ki - onu statik bir yöntem olarak kullanmıyorum. Aksi takdirde zaten statik olurdu. Bu yüzden PyCharm, bunu iyi bir neden olmadan yapmayı tavsiye ediyor (?). "Geriye kalan avantajlar, eğer mevcutsa, muhtemelen marjinaldir" --- evet, kesinlikle. Ama durum buysa - bu PyCharm'dan aptalca bir tavsiye
zerkms

1
@zerkms, bazı büyüleyici örneklerde işler böyle :-)
Jan Vlcinsky

2
Statik yöntemler, iyi bir yazılım geliştirmenin düşmanıdır. Birçok prensibi geçersiz kılarlar, bu yüzden bitdaha hızlı koşmak önemli değildir (çünkü her iki durumda da hızlı çalışırlar) ve bildiğiniz gibi bilgisayarların bunchbelleği vardır, bu yüzden artık bir sorun değildir. Ayrıca ilk düşüncenize dikkat edin: Bu, nesneye yönelik değil, prosedürel bir davranıştır.
AmirHossein

4

Eğer söz etmemişlerdir beri selfde baryöntem gövdesine eğer, pycharm soruyor olabilir yapmak istedim barstatik. Java gibi diğer programlama dillerinde, statik bir yöntem bildirmek için bariz nedenler vardır. Python'da, bir statik yöntemin (AFIK) tek gerçek yararı, onu sınıfın bir örneği olmadan çağırabilmektir. Bununla birlikte, tek sebebiniz buysa, muhtemelen en üst düzey bir işleve gitmeniz daha iyi - burada not edildiği gibi .

Kısacası, neden orada olduğundan yüzde yüz emin değilim. Muhtemelen gelecek sürümde kaldıracaklarını tahmin ediyorum.


3

Test örnek oynatıcımı kullanarak işlevimi yanlışlıkla yazdığımı fark etmediğim için bu hata mesajı bana bir grup yardımcı oldu

my_player.attributes[item] 

doğru yol yerine

self.attributes[item]

2

Pycharm'ın bunu bir uyarı olarak yapmasının nedeni, çünkü Python, hiçbir statik yöntemi çağırırken ilk argüman olarak self'i iletecektir (@staticmethod'u eklemeyin). Pycharm bunu biliyor.

Misal:

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'lıyım, Java'da "self" "bu" olarak adlandırılır, sınıf yönteminde argüman olarak self (veya bunu) yazmanıza gerek yoktur. Yöntemin içinde ihtiyaç duyduğunuzda kendini çağırabilirsiniz. Ancak Python, kendini bir yöntem argümanı olarak "geçmek zorundadır".

Bunu anlayarak @ BobStein yanıtı olarak herhangi bir Geçici Çözüme ihtiyacınız yoktur.


selfÖyleyse ne geçer ?
zerkms

@zerkms '@staticmethod' 'kendi'i' geçmiyor
Junyu Wu

Az önce size alıntı yaptım: "Python ilk argüman olarak kendini geçecek ... Pycharm bunu biliyor." Ne olmuş yani? Pycharm bunu biliyor, biliyorum. Yöntemi işaretlemenin nedeni nedir?
zerkms

@zerkms, çünkü Pycharm ilk yönteminizin paramının "öz" olmayabileceğini düşünüyor. Normalde ppl bir yöntem parametresi tasarlamaz ve asla kullanmaz. Pycharm, statik bir yöntem oluşturduğunuzu düşünüyor ve ilk parametrenin "self" olmadığını fark etmediğinden, varsayılan olarak bir uyarı koyar. Programlama dili tasarımından kaynaklanan bu karışıklık. Karışıklığı önlemek için programlama tasarımını takip etmenizi (iyi bir model olmasa bile), "statik yöntem" eklemenizi öneririm. Bir "benlik" eklerseniz, sonra tercih ederseniz asla kullanmayın. Diyorum ki, programlama tasarımını anlayarak farklı bir fikir.
Junyu Wu

1

Biraz dağınık olabilir, ancak bazen erişmeniz gerekmez self, ancak yöntemi sınıfta tutmayı ve statik hale getirmemeyi tercih edersiniz . Ya da bir grup çirkin dekoratör eklemekten kaçınmak istersiniz. İşte bu durum için bazı olası geçici çözümler.

Metodunuzun yalnızca yan etkileri varsa ve ne getireceği umurunuzda değilse:

def bar(self):
    doing_something_without_self()
    return self

Dönüş değerine ihtiyacınız varsa:

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

Şimdi yönteminiz kullanıyor selfve uyarı ortadan kalkıyor!

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.