那么,一种告诉函数你想如何处理它的参数的方法是有合理的默认值(使得函数默认处理所有的原始类型),同时能够指定你喜欢的任何调整(即,具有短和缺席逐默认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