Python jeneratörleri ve işlevleri neden "def" anahtar kelimesini paylaşıyor?


10

Aşağıdakileri göz önünde bulundur:

def some_function():
    return 1

def some_generator():
    yield 1

Yukarıdaki kodda some_function, bir işlev, some_generatorbir jeneratör. Oldukça benzer görünüyorlar.

Kod okurken sahip olduğum sorun, ben yieldaslında bir işlev veya jeneratör olup olmadığını belirlemek önce bir "işlev" her anahtar kelime aramak için anahtar kelime arıyor gerekir!

Bana öyle geliyor ki, jeneratörler için farklı bir anahtar kelime kullanmak daha mantıklı olurdu, örneğin:

gen some_generator():
    yield 1

defAnahtar kelimeyi hem üreticiler hem de işlevler için kullanmanın yararları nelerdir ? Ayrı işlevlere ve üreticilere neden yeni bir anahtar kelime eklenmedi?


Gerçek cevabı bilmiyorum, ama genellikle listeleri döndüren fonksiyonları yazmaya başlıyorum, sonra doğru göründüğünde jeneratörlere dönüşüyorum. Sözdizimi eşleşmesi bunu daha doğal hale getirir.
Robot Gort

2
Gibi bir şey kullanmanın @StevenBurnap Derek öneri genyerine defo dönüşümü önemli ölçüde daha fazla külfetli yapmazdım.
jamesdlin

2
Genel olarak, dil tasarımcıları genellikle gereksiz anahtar kelimeler eklemekten kaçınırlar. Ekledikleri her anahtar kelime, programların başka amaçlarla kullanmasına izin verilmeyen bir tanımlayıcıdır.
jamesdlin

@jamesdlin: Ancak soru, yeni bir anahtar kelimenin gerekli olacağını savunuyor .
Giorgio

1
@jamesdlin: Elbette işlevleri ve jeneratörleri bedenlerine bakarak ayırt edebilirsiniz, ancak soru farklı anahtar kelimeler kullanmanın kodu daha okunabilir hale getireceğini savunuyor.
Giorgio

Yanıtlar:


14

"Hem jeneratörler hem de işlevler için def anahtar sözcüğünü kullanmanın yararları nelerdir?"

Mekanik olarak farklı olmalarına rağmen, pratikte bunları kullandığımda genellikle kavramsal olarak benim için etkili bir şekilde aynıdırlar ( range()vs çağırmayı pek düşünmüyorum xrange()).

Bununla birlikte, işlevin ne hakkında hızlı bir şekilde olduğunu anlamak için, bir şeyin kullanımıyla kaybolduğuna katılıyorum def, ancak işler işlevle başlamak için çok şaşırtılmamalıdır.

Örtük return Nonebir koşul bile, bir koşulun uzun süreli koşullardan sonra amaçlanan davranışını karıştırabilir (olduğu return Nonegibi, mantıkta son bir davranış veya gözetim olarak düşünülmüştür). Ama bunlar sadece benim inancım.

Argümün özellikle ikna edici olduğunu düşünmüyorum, bu yüzden sadece PEP 255'e erteleyeceğim :

Sorun: Jeneratör işlevlerini jeneratör olmayan işlevlerden ayırmak için "def" yerine başka bir yeni anahtar kelime (örneğin "gen" veya "jeneratör") ekleyin veya sözdizimini başka şekilde değiştirin.

Con: Uygulamada (onlar hakkında nasıl düşündüklerini), jeneratörler ise şunlardır fonksiyonlar, ancak bükülme ile onlar devam ettirilebilir olduğunu. Nasıl kurulduklarının mekaniği nispeten küçük bir teknik konudur ve yeni bir anahtar kelime getirmek, jeneratörlerin nasıl başladığı (bir jeneratörün hayatının hayati ama küçük bir kısmı) mekaniğini yararsız bir şekilde vurgulayacaktır.

Pro: Gerçekte (onlar hakkında nasıl düşünüyorsunuz), jeneratör fonksiyonları aslında jeneratör gibi yineleyiciler üreten fabrika işlevleridir. Bu açıdan üreteç olmayan işlevlerden radikal olarak farklıdırlar, bir işlevden çok bir yapıcı gibi davranırlar, bu nedenle "def" nin yeniden kullanılması en iyisi kafa karıştırıcıdır. Vücuda gömülü bir "verim" ifadesi, anlambilimin çok farklı olduğuna dair yeterli uyarı değildir.

BDFL: "def" kalır. Her iki tarafta da hiçbir argüman tamamen ikna edici değil, bu yüzden dil tasarımcımın sezgisine danıştım. Bana PEP'de önerilen sözdiziminin tam olarak doğru olduğunu söylüyor - çok sıcak değil, çok soğuk değil. Ancak, Yunan mitolojisinde Delphi'deki Oracle gibi, bana nedenini söylemiyor, bu yüzden PEP sözdizimine karşı argümanlar için bir çürümem yok. Ben gelebilir en iyi (zaten yapılan çürütme ile kabul ... dışında) "FUD" dir. Eğer bu ilk günden itibaren dilin bir parçası olsaydı, Andrew Kuchling'in "Python Warts" sayfasını yapmış olabileceğinden şüpheliyim.


1
PEP 492'de çok benzer şekilde çalışan yeni await(ve async withve async for) sözdizimi yapılarının , yerine kullanıldıkları işlevin bir adil yerine kullanılarak bildirilmesini gerektirdiğini belirtmek gerekir . yield fromasync defdef
Feuermurmel

2
  1. Yeni anahtar kelimeler eklemek mevcut programların bozulmasına neden olabilir. Dil tasarımcıları genellikle, özellikle dil zaten bazı popülerlik kazandıktan sonra eklenen dil özellikleri için yeni anahtar kelimeler eklemekten kaçınır. Ekledikleri her anahtar kelime, programların başka amaçlar için kullanılmasına izin verilmeyen bir tanımlayıcıdır, bu nedenle bir anahtar kelime eklemek mevcut programları bozabilir. Dil tasarımcıları yeni bir anahtar kelimenin avantajlarını maliyetlere göre değerlendirmek zorundadır.

  2. Jeneratörler için ayrı bir anahtar kelime tanımlamanın çok fayda sağlayacağından şüpheliyim . Bir sembolün bir işlevin adına mı yoksa bir jeneratörün adına mı karşılık geldiğini anlamak, arayanlar için önemli olan bir şeydir ve arayanlar, onu uygulamak için hangi anahtar kelimenin kullanıldığına bakmak zorunda değildir (ve bazen yapamazlar). Daha iyi adlandırma kuralları ve belgelemenin sorumluluğu budur.


1

Jeneratörler tembel olarak değerlendirilen işlevlerdir. Temelde aynı şey oldukları göz önüne alındığında, aynı anahtar kelimeyi kullanacakları mantıklıdır. Bir seçenek, belirli bir örnek için hangisinin hangisi olduğunu tanımlamak için bir yorum kullanmak olabilir:

def some_function(): #This is a function.
    return 1

def some_generator(): #This is a generator.
    yield 1

0

Ben daha Pitonik olduğu için tahmin ediyorum ama ne biliyorum? ;)

Gerçekten bu kadar önemli olduğunu düşünmüyorum. Benim için hatırlamak daha kolay çünkü ikisini de ezberlemeye gerek yok.

DÜZENLEME: PEP, orada araştırma yapabileceğinizi söyleyebilir.


Teşekkürler! Aslında, PEP diyor! Artıları / eksileri ve jeneratörler için yeni bir anahtar kelime ile ilgili nihai karar için PEP-255'e bakınız .
Derek Kwok

Pythonic anlamı ile: "Python'da nasıl yapılır?"
Giorgio
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.