Jeneratörler tembel olarak değerlendiriyorlar returnya yieldda kodunuzda hata ayıklarken veya bir istisna atıldığında farklı davranıyorlar.
İle returnSepetinde olur herhangi istisna generatorhakkında hiçbir şey bilmeyecek generate_allne zaman çünkü bu, generatorgerçekten yürütülür zaten bırakmış generate_allişlevi. yieldOrada ile geri generate_allizleme olacak.
def generator(some_list):
for i in some_list:
raise Exception('exception happened :-)')
yield i
def generate_all():
some_list = [1,2,3]
return generator(some_list)
for item in generate_all():
...
Exception Traceback (most recent call last)
<ipython-input-3-b19085eab3e1> in <module>
8 return generator(some_list)
9
---> 10 for item in generate_all():
11 ...
<ipython-input-3-b19085eab3e1> in generator(some_list)
1 def generator(some_list):
2 for i in some_list:
----> 3 raise Exception('exception happened :-)')
4 yield i
5
Exception: exception happened :-)
Ve eğer kullanıyorsa yield from:
def generate_all():
some_list = [1,2,3]
yield from generator(some_list)
for item in generate_all():
...
Exception Traceback (most recent call last)
<ipython-input-4-be322887df35> in <module>
8 yield from generator(some_list)
9
---> 10 for item in generate_all():
11 ...
<ipython-input-4-be322887df35> in generate_all()
6 def generate_all():
7 some_list = [1,2,3]
----> 8 yield from generator(some_list)
9
10 for item in generate_all():
<ipython-input-4-be322887df35> in generator(some_list)
1 def generator(some_list):
2 for i in some_list:
----> 3 raise Exception('exception happened :-)')
4 yield i
5
Exception: exception happened :-)
Ancak bu, performans maliyetine neden olur. İlave jeneratör katmanının bir miktar ek yükü vardır. Bu yüzden (veya ) returngenellikle biraz daha hızlı olacaktır . Çoğu durumda bu çok önemli olmayacaktır, çünkü jeneratörde ne yaparsanız yapın tipik olarak çalışma zamanına hakim olur, böylece ek katman fark edilmeyecektir.yield from ...for item in ...: yield item
Bununla birlikte yield, bazı ek avantajları vardır: Tek bir yinelenebilirle sınırlı değilsiniz, ayrıca kolayca ek öğeler de verebilirsiniz:
def generator(some_list):
for i in some_list:
yield i
def generate_all():
some_list = [1,2,3]
yield 'start'
yield from generator(some_list)
yield 'end'
for item in generate_all():
print(item)
start
1
2
3
end
Sizin durumunuzda işlemler oldukça basittir ve bunun için birden fazla işlev oluşturmanın gerekli olup olmadığını bilmiyorum, biri kolayca dahili mapveya jeneratör ifadesini kullanabilir:
map(do_something, get_the_list()) # map
(do_something(i) for i in get_the_list()) # generator expression
Her ikisi de aynı olmalıdır (istisnalar olduğunda bazı farklılıklar hariç). Ve daha açıklayıcı bir isme ihtiyaçları varsa, onları yine de bir işlevde sarabilirsiniz.
Yerleşik tekrarlanabilirler üzerinde çok yaygın işlemleri saran birden fazla yardımcı vardır ve yerleşik modülde başka işlemler de bulunabilir itertools. Böyle basit durumlarda sadece bunlara başvururum ve sadece önemsiz durumlar için kendi jeneratörlerinizi yazarım.
Ancak gerçek kodunuzun daha karmaşık olduğunu varsayarım ki bu geçerli olmayabilir, ancak alternatiflerden bahsetmeden bunun tam bir cevap olmayacağını düşündüm.