Python'da değer döndüren işlevleri nasıl adlandırmalıyım?


13

Python'daki işlevlerim için isim seçme konusunda kafam karıştı . Bazen Python yerleşik işlevleri zorunludur : printfunction ve string method find. Bazen böyle değildirler: örneğin lenadı gibi zorunlu değildir calculate_lenve typedeğildir find_type.

Anlamadığımız printbir değer döndürüyor (yani None) ve bir şey yapar (yani ekranda bir dize gösterir), bu yüzden adı zorunludur.

Ancak lenkullandığımız bir değer döndürür ve bir şey yapar (yani bir sekansta veya eşlemede kaç öğe olduğunu hesaplar.) Ve adı zorunlu değildir . Öte yandan, findstring yöntemi (as len) kullandığımız ve bir şeyler yaptığımız bir değer döndürür ve adı zorunludur .

Bu soruyu soran şey, incelenmek üzere Sezar şifresini kullanarak dizeyi şifreleyen ve şifresini çözen bir komut dosyası koymam. Hakem şunları söyledi:

Sadece bağırsak hissi: fonksiyonlar bir şeyler yapar. Yani bir fonksiyon için iyi bir isim bir zorunluluktur: Onun rotate_letteryerine kullanmak istiyorum rotated_letter.

rotated_lettersayı ile döndürülmüş bir harfi temsil eden tek harfli bir dize döndürür. Neyin daha iyi olduğunu bilmiyorum , rastgele bir modülde işlev rotated_lettergibi bir değer döndürdüğü için kullandım , değil .randintgenerate_randint

Bu durumda, kullanılacak değeri döndüren bir işlevi nasıl adlandırmalıyım? Adı zorunlu mu yoksa sadece bir isim mi yapmalıyım ? Diğer durumlarda bu gibi nasıl yapılacağını açıktır boole fonksiyonları gibi is_evenve is_palindromebiz sadece bir gibi yap evet / hayır soru ve ayrıca fonksiyonları sadece yapmak ve dönüş olmayan kullanılan değerler (yani Nonegibi), printve liste yöntemiyle sort.


aslında işlevi adlandırırken zorunlulukları kullanmak için çok yaygın bir uygulamadır (bir sözleşme söyleyebilirim). Örneğin, rotated_letter işlevinin döndürülmüş harfini depolayan bir değişkeni nasıl adlandırırsınız?
JoulinRouge

Bu, bazı örneklerinizi düşünmenin iyi bir yolu değil. lenÖrneğin, "uzunluk" olarak daha iyi düşünülür - argümanının meta düzeyinde bir açıklaması alıyorsunuz.
Izkata

Yanıtlar:


10

Makul olan yerlerde fiiller kullanın, isimler daha kısa ve açıksa

Çoğu zaman, fonksiyonlar (zorunlu) fiiller olmalı ve sınıflar, değişkenler ve parametreler isimler olmalıdır. Nitelikler, kullanılarak oluşturulanlar da dahil olmak üzere isimler olmalıdır @property. Bu, özellikle yan etkileri olan fonksiyonlar için geçerlidir. [1] Bir işlev bir şey döndürürse, fiilin bir şey ekleyip eklemediğini veya sadece "gürültü" olup olmadığını değerlendirmelisiniz:

  • make_list(foo)vs list(foo).: İsmin okunması fiilden daha kolaydır. Ayrıca, listaslında bir sınıftır ve sınıflar isimler olmalıdır.
  • open(foo)vs file(foo).: Fiil okunması isimden daha kolaydır ve bir fiile "seçenekler" vermek bir isimden daha mantıklıdır, bu nedenle isim Python 3'te kaldırılmıştır. open()"Standart" [2] Python 3'te dosya nesneleri oluşturmak için.
  • foo.get_bar()vs. foo.bar()vs. foo.bar(varsayalım foove barher ikisi de isimdir): İlk seçenek doğrudur, çünkü "get" zaten bilmediğimiz hiçbir şeyi eklemez. Bir alma eğer ikinci uygundur bara out foopotansiyel pahalı bir işlemdir ve / veya yan etkileri (ayrıca düşünebilirsiniz taşır Bar(foo)eğer Barbir sınıftır). Üçüncüsü, bunun yan etkisi olmayan ucuz bir işlem olması ve uygun uygulamaların pahalı olması muhtemel değilse uygundur .
  • xs.sort()vs sorted(xs)eğer xsilk zorunludur: listesidir sırala listesi. Listeyi yerinde değiştirir ve hiçbir şey döndürmez. İkincisi bildirim niteliğindedir: Sıralanan ve tam olarak döndürdüğü liste. Her ikisi de fiildir.

[1]: Bunları birleştirmek için zorlayıcı bir tasarım nedeniniz olmadıkça genellikle bir değer döndürmek ve yan etkilere sahip olmak birbirini dışlar. Dolayısıyla, yan etkileri olan bir işlev muhtemelen hiçbir şey döndürmemeli ve dolayısıyla bir isim yapmak çok az mantıklı olacaktır.
[2]: ioModülde dosya arabelleğe alma, otomatik metin enkoderi çözme, vb. Eklemek veya kaldırmak için kullanılabilecek orta derecede daha düşük düzeyli işlemler vardır ve bunlar çoğunlukla nesne yönelimli sınıflar oldukları için isimdir. Çoğu kullanıcının bu şeylerle doğrudan oynamasına gerek yoktur; bunun yerine, open()uygun bir sınıfı seçer ve otomatik olarak başlatır.


Teşekkür ederim! In " foo.get_bar() vs.` foo.bar ()` vs foo.bar" arasındaki fark nedir saniye ve üçte ?
Mahmood Muhammad Nageeb

Üçüncüsü, bir özellik veya çıplak bir özelliktir. İkincisi bir yöntemdir.
Kevin

Yani, anlarsam, rotated_letterzorunluluk göstermemeli ve beyanda bulunmamalı, değil mi?
Mahmood Muhammad Nageeb

Bu durumda letterbağlamın ima edilip edilmediğinden emin değilim .
Kevin

Bahsetmek için +1 listbir sınıftır
Dušan Maďar

0

rotated_letterbir yöntem gibi görünmüyor. Bir mülke benziyor. Bu, ilk fikrin şunları yapmak olduğu anlamına gelir:

var letter = caesar.rotated_letter

letterişlev değil, string türünde bir değer içermesi bekleniyor . Oradan, ya farklı bir isim seçtiniz, örneğin:

def rotate_letter(self):
    pass

veya bunun yerine bir özellik kullanırsınız:

@property
def rotated_letter(self):
    return self.whatever

lenve typeböyle adlandırılır, çünkü başka bir adın yazılması uzun olur. Çok kullanılırlar ve her Python programcısının öğreneceği temel Python işlevlerinin özel bir statüsü vardır, bu da adlarını üçüncü taraf kitaplıklarının adlarından çok daha alakasız hale getirir.

lenÖzellikle, içeri yapmaması gereken ne iyi bir örnektir senin kod, aşağıdaki gibi tam adlarını kullanmak için beklenen konum length(kısa hali çok popüler gibi olmadıkça maxgibi, bir fiil) ve kullanımı compute_length. Veya bir özellik olabilir: len([1, 5, 6])olur [1, 5, 6].length. Örneğin, C #, daha sonra formu kullanılır: new [] { ... }.Length.

Tarihsel nedenlerin de olabileceğini unutmayın len: C # gibi tercih edilen Count, genellikle bir yöntem olan diğer diller (davranış maalesef .NET Framework üzerinden tutarsız olsa da). Countbir fiildir, bu yüzden sezgisel olarak, onu bir yöntem olarak çağırmaya eğilimlisiniz.

Değerleri döndürme veya bir eylem gerçekleştirme

Bir işlevin her zaman bir eylem gerçekleştirmesi beklenir. Bir değeri zar zor döndürürse, bir özellik olmalıdır. Aşağıdaki durumlarda işlevin bir özelliğe dönüştürülmesi gerektiğine dair bir ipucunuz vardır:

  • İşlev zar zor bir return ...ifade içeriyor ,

  • Doğal olarak aklınıza gelen işlevin adı get_something, olduğu gibi product.get_price().

Şimdi, bir işleviniz varsa, dört türden biri olabilir:

  • Saf olabilir, yani çevreyi etkilemeden bir değer döndürür. Örnek: road.measure_distance().

  • Hiçbir şey iade etmeden çevreyi etkileyebilir. Örnek: product_database.remove_record(1234).

  • Çevreyi etkileyebilir ve bir değer döndürebilir. Örnek: value.increment()gibi kullanılır value++.

  • Hiçbir şey yapamaz ve hiçbir şey getiremez. Örnek: time.sleep(1).

Adın, işlevin türü hakkında güçlü bir ipucu verebileceği birkaç durum vardır, ancak birçok durumda, türü adından zar zor bilemezsiniz.


Cevabın "evet" olduğunu varsayıyorum, ama şunu sormalıyım: Tamamen Python perspektifinden mi cevap veriyorsunuz? Çünkü diğer dillerde fonksiyon ile mülk arasındaki ayrım her zaman doğru değildir; bir fonksiyonun "bir eylem gerçekleştirmesi" gerektiği de doğru değildir. Bu Python'daki sözleşme mi? (Python yazıyorum ama tüm PEP'leri okumadım ve kesinlikle bir uzman DEĞİLİM.
Andres F.

@AndresF .: Python açısından cevap veriyorum. Özelliklerin olmadığı Java gibi dillerde getSomethingve setSomethingözellikler yerine kullanılan genel adlardır.
Arseni Mourzenko
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.