Yinelenecek nesnelerin birkaç "kaynağı" olan bir yineleyici oluşturmak istiyorum. Ben __next__()
yöntemini, kaynağı seçme olanağı sunan isteğe bağlı bir anahtar kelime argümanını (anahtar kelime argümanı anlamına gelmez, sadece bir kaynağı rastgele seçersiniz) verebilmeyi isterdim. daha sonra, gerçek bir yineleyici infinite_iterator yapmak def __next__(self, **kwargs):
yazmak istersenBir yineleyici oluşturma ve çeşitli yineleme kaynakları arasından seçim yapın.
#!/usr/bin/env python3
import random
class infinite_iterator(object):
def __init__(self, sources):
self.collector = []
for s in sources:
random.shuffle(s)
self.collector.append([])
self.sources = sources
def __iter__(self):
return self
# Workaround: calling it next instead of __next__
# (not the python3 way...)
def next(self, **kwargs):
sce_nb = random.choice([ n for n in range(len(self.sources)) ])
if 'choice' in kwargs:
sce_nb = kwargs['choice']
self.collector[sce_nb].append(self.sources[sce_nb][0])
output = self.sources[sce_nb].pop(0)
# Repopulate any empty 'source'
if not self.sources[sce_nb]:
(self.sources[sce_nb], self.collector[sce_nb]) = \
(self.collector[sce_nb], self.sources[sce_nb])
random.shuffle(self.sources[sce_nb])
return output
S = infinite_iterator([["Adam", "Paul", "Oliver", "Aaron", "Joshua", "Jack"],
["Mary", "Sophia", "Emily", "Isobel", "Grace", "Alice", "Lucy"]])
print("Any name: " + S.next())
print("Any girl's name: " + S.next(choice=1))
print("Any boy's name: " + S.next(choice=0))
Sorun şu ki: geçici bir çözüm olarak bu yetersiz kod yazdık, böylece __next__()
nedenleri sorunları (aşağıya bakınız) kullanarak
bir hata (2d çizgi)
print("Any name: " + next(S))
print("Any girl's name: " + next(S, choice=1))
print("Any boy's name: " + next(S, choice=0))
ama olsun: Tabi ki yazmak istiyorum
TypeError: next() takes no keyword arguments
Bu çağrı next(S, choice=1)
, nesne içinde tanımlı __next__()
işlevini kullanır. Bu hatadan dolayı, bir yandan bunun aslında olmadığını düşünüyorum. Bu beklenebilirdi, çünkü tam olarak bir tekrar tanımı değil, çünkü sonsuz yineleyici bir "İteratör nesnesi" miras almaz (anladığım kadarıyla, böyle bir nesne yoktur). Ama başka bir yandan, sadece next(S)
'u ararsam ve bu durumda, benim__next__()
yöntemim gerçekten çağrılır (rastgele bir liste üzerinde yinelemeyi seçer). Son olarak, böyle bir yineleyicinin gerçekleştirilmesi için bir çözüm var mıdır? Bu değer option
değişkene geçirilen alır, bu işleri
import random
def selector(sources):
option = None
while True:
if option is None:
option = yield random.choice(random.choice(sources))
else:
option = yield random.choice(sources[option])
s = selector([["Adam", "Paul", "Oliver", "Aaron", "Joshua", "Jack"],
["Mary", "Sophia", "Emily", "Isobel", "Grace", "Alice", "Lucy"]])
print("Any name: " + next(s))
print("Any girl's name: " + s.send(1))
print("Any boy's name: " + s.send(0))
yolu send
diyoruz her zaman geçerli:
Tamam, bu yüzden '__next__' işlevini şu şekilde çağırmak imkansız:' next (s, choice = 1) '? – zezollo
Yineleyici protokolü (veya' next' builtin ') tanımlanmış değil, ve bu tanımı değiştiremezsiniz, o yüzden hayır, ama 'gönder' çalışır, özellikle 'ileri' kullanarak neden takıldığınızdan emin değilim. – tzaman