這聽起來像你的,比方說,10項list
,然後你要在list
運行在每個項目50個功能,而且你不想寫50 for
循環。
一種可能性是寫一個包裝了一個功能:
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
s結果,你不需要。
- 在Python 3中,
map
返回一個迭代器而不是list
,所以它不會真正執行函數,除非您以某種方式遍歷它。 (你顯然使用2.x的今天,因爲你print
聲明,但據推測有一天你會切換到3.x的)
可以解決使用itertools.imap
(發電機表達或)這些問題而不是map
(或列表理解)並通過例如將其饋送到0大小的deque
來處置該可迭代。但在那個時候,你的代碼在做什麼並不完全清楚。
同時,明確地寫入函數意味着在發現需要時很容易修改成例如第二個版本。
我不明白你的觀點。 for循環有什麼不好的地方?你想要一個班輪嗎?然後使用'map(lambda thing:thing.some_function(),self.list_of_objects)' 如果您的問題有其他更深層次的動機,例如設計原則或其他東西,請澄清一下。 –
假設我有50個步驟在一個節點上進行處理,這意味着每個步驟的循環數爲50。因此,對於節點中的節點:run_cmd(「ls -l)等等。因爲我知道我想在移動到rm步驟之前在所有節點上運行此相同的命令,應該有辦法將它們批處理? –
聽起來像你的問題是你有50個不同的函數,你想在列表中的所有10個元素上調用它們,你不想寫50個'for'循環,對吧? – abarnert