那麼,一種告訴函數你想如何處理它的參數的方法是有合理的默認值(使得函數默認處理所有的原始類型),同時能夠指定你喜歡的任何調整(即,具有短和缺席逐默認fmt
字符串),如:
def smart_func(*args, **kw):
"""If 'kw' contains an 'fmt' parameter,
it must be a list containing positions of arguments,
that should be treated as if they were of opposite 'kind'
(i.e. iterables will be treated as non-iterables and vise-versa)
The 'kind' of a positional argument (i.e. whether it as an iterable)
is inferred by trying to call 'iter()' on the argument.
"""
fmt = kw.get('fmt', [])
def is_iter(it):
try:
iter(it)
return True
except TypeError:
return False
for i,arg in enumerate(args):
arg_is_iterable = is_iter(arg)
treat_arg_as_iterable = ((not arg_is_iterable)
if (i in fmt) else arg_is_iterable)
print arg, arg_is_iterable, treat_arg_as_iterable
這給出:
>>> smart_func()
>>> smart_func(1, 2, [])
1 False False
2 False False
[] True True
>>> smart_func(1, 2, [], fmt=[])
1 False False
2 False False
[] True True
>>> smart_func(1, 2, [], fmt=[0])
1 False True
2 False False
[] True True
>>> smart_func(1, 2, [], fmt=[0,2])
1 False True
2 False False
[] True False
擴展該功能(尋找最長可迭代的長度,等等),一個可以構造一個smart-zip
你在說什麼。
[PS] 另一種方法是調用下列方式功能:
smart_func(s='abc', 1, arr=[0,1], [1,2], fmt={'s':'non-iter','some_arr':'iter'})
和具備的功能與您提供的參數名稱('s'
和'arr'
,注,有在函數簽名中沒有這樣的名稱,因爲它與上面的)到'fmt'
「類型提示」(即'iter'
使參數被認爲是可迭代的,並且'non-iter'
是不可迭代的)相同。當然,這種方法可以與上述「切換式」結合使用。
Python的方式是調用者是顯式的,並將非迭代轉換爲迭代。 'zip(my_list,itertools.repeat(42))' 這與添加int和字符串時必須編寫42 + int('100')'相同。 添加魔術轉換會導致猜測和混淆。 – 2010-03-20 15:31:08
是的,沒錯。但是我需要多次調用這個函數,然後每次調用之前都必須進行檢查。這看起來有點多餘。 - 所以,我需要這個功能的原因是相當狹窄和明確的,但是我希望儘可能普遍地具有該功能的潛在能力。 – Debilski 2010-03-20 17:46:30