反復するオブジェクトの「ソース」がいくつかあるイテレータを作成したいとします。私は、__next__()
メソッドにオプションのキーワード引数を与えて、ソースを選択することができるようにしたいと考えています(キーワード引数は無作為にソースを選択するだけです)。その後の、私は本当のIteratorをinfinite_iterator作るためにdef __next__(self, **kwargs):
を書きたい場合はイテレータを作成し、いくつかの反復元を選択する
#!/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))
問題は、次のとおりです。回避策として、私はこのあっけなくコードを書いているので、__next__()
原因の問題(下記参照)を使用して
もちろん、私が書きたい:
print("Any name: " + next(S))
print("Any girl's name: " + next(S, choice=1))
print("Any boy's name: " + next(S, choice=0))
が、エラー(2Dライン)を取得:
TypeError: next() takes no keyword arguments
私はこの呼び出しでnext(S, choice=1)
がオブジェクトに定義された__next__()
関数を使用すると考えました。このエラーのために、私は実際にはそうではないと考えています。 infinite_iteratorは "Iteratorオブジェクト"から継承していないので、これはまったくの再定義ではないので、これは期待できます(私が理解する限り、そのようなオブジェクトはありません)。しかし、もう1つの手で、私はnext(S)
と呼んだだけで、この場合、私の__next__()
というメソッドが実際に呼び出されます(これは反復処理のためにリストをランダムに選択します)。
最後に、このようなイテレータを実現するソリューションはありますか?
これで '__next__'を呼び出すことはできません:' next(s、choice = 1) '? – zezollo
これはイテレータプロトコル(または' next'組み込み関数)がどのように定義されているのか、あなたはその定義を変更することはできませんので、いいえ、しかし、 'send'が動作します、なぜあなたは'特に 'を使用して固執しているのか分かりません。 – tzaman