list
たとえば、10 個のアイテムがあり、 の各アイテムに対して 50 個の関数を実行したいのに、50 個のループlist
を記述する必要はないように思えます。for
1 つの可能性は、それをラップする関数を作成することです。
def apply(method, seq):
for item in seq:
method(item)
次に、これの代わりに:
for thing in self.list_of_objects: # Yuck!!
thing.some_function()
for thing in self.list_of_objects: # Yuck!!
thing.other_function()
for thing in self.list_of_objects: # Yuck!!
thing.third_function()
# ... 47 more times
あなたはこれを行うことができます:
apply(ThingClass.some_function, self.list_of_objects)
apply(ThingClass.other_function, self.list_of_objects)
apply(ThingClass.third_function, self.list_of_objects)
# ... 47 more times
関数とメソッドは、他のものと同様に、Python のファーストクラス オブジェクトであるため、他の関数に簡単に渡すことができます。もちろんfirst_thing.some_function
、 とsecond_thing.some_function
は実際には異なるバインドされたメソッドです。self
トリックは、クラスからバインドされていないメソッドを取得し、明示的なパラメーターとしてオブジェクトを渡すことができるということです。first_thing.some_function
( 、ThingClass.some_function
、type(first_thing.some_function)
、および を印刷してtype(ThingClass.some_function)
、対話型インタープリターで操作してみてください。)
もちろん、これは、これらすべてのアイテムが同じメソッドを持っている理由は、それらが同じクラスのインスタンスであるためだと仮定しています。それが正しくなく、代わりにダック タイピングに依存している場合は、少し異なるものが必要です。
def apply(methodname, seq):
for item in seq:
getattr(item, methodname)()
apply('some_function', self.list_of_objects)
# ... 49 more times
ここでのトリックは、getattr
実行時に任意のメソッドまたはメンバーを名前で取得できる関数です。
しかし、よく考えてみると、ここで本当に必要なのは、これら 50 個のバインドされていないメソッドまたは名前を反復処理することであり、同じことをまったく繰り返す必要はありません。例えば:
for name in ('some_function', 'other_function', 'third_function',
# ... 47 more names
):
for obj in self.list_of_objects:
getattr(obj, name)()
メソッドの最初のバージョンはapply
、ビルトインmap
(Python 2.x のみで、3.x ではなく) またはリスト内包表記で簡単に置き換えることができることに注意してください。ただし、そうしない理由がいくつかあります。
map
一般に、副作用のために関数を呼び出すだけの場合、使用するスタイルや理解が疑わしいと見なされます。
- 50*10 だけではなく、多数のアイテムがある場合
list
、必要のない結果を構築するためにメモリと時間が無駄になります。
- Python 3 では、
map
の代わりにイテレータを返すlist
ため、何らかの方法で反復しない限り、実際には関数をまったく実行しません。(あなたのprint
発言から、あなたは明らかに 2.x を使用していますが、いずれ 3.x に切り替えることになるでしょう。)
これらの問題は、(またはリスト内包itertools.imap
表記) の代わりに (またはジェネレーター式) を使用map
し、たとえば 0 サイズのdeque
. しかし、その時点では、コードが何をしているのか正確にはわかりません。
一方、関数を明示的に記述するということは、必要に応じて、たとえば 2 番目のバージョンに簡単に変更できることを意味します。