我最近创建了一个 @sequenceable 装饰器,它可以应用于任何接受一个参数的函数,并使其自动适用于任何序列。这是代码(Python 2.5):
def sequenceable(func):
def newfunc(arg):
if hasattr(arg, '__iter__'):
if isinstance(arg, dict):
return dict((k, func(v)) for k, v in arg.iteritems())
else:
return map(func, arg)
else:
return func(arg)
return newfunc
正在使用:
@sequenceable
def unixtime(dt):
return int(dt.strftime('%s'))
>>> unixtime(datetime.now())
1291318284
>>> unixtime([datetime.now(), datetime(2010, 12, 3)])
[1291318291, 1291352400]
>>> unixtime({'start': datetime.now(), 'end': datetime(2010, 12, 3)})
{'start': 1291318301, 'end': 1291352400}
我的问题是:
使用此代码?
已经做了我正在做的事情?
最佳答案
这是一个可怕的想法。这本质上是松散的打字。鸭子打字到此为止
应该采取的东西,海事组织。
考虑一下:
def pluralize(f):
def on_seq(seq):
return [f(x) for x in seq]
def on_dict(d):
return dict((k, f(v)) for k, v in d.iteritems())
f.on_dict = on_dict
f.on_seq = on_seq
return f
你的例子然后变成
@pluralize
def unixtime(dt):
return int(dt.strftime('%s'))
unixtime.on_seq([datetime.now(), datetime(2010, 12, 3)])
unixtime.on_dict({'start': datetime.now(), 'end': datetime(2010, 12, 3)})
这样做仍然需要调用者知道(在鸭子类型的准确性范围内)传入的内容,并且不会向实际函数添加任何类型检查开销。它也适用于任何类似 dict 的对象,而您的原始解决方案取决于它是
dict
的实际子类。关于python - 我的装饰器有多糟糕?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/4339099/