有没有办法将函数转换为接受在函数之前计算的可调用函数?

时间:2014-05-07 15:37:18

标签: python partial functools

假设我有一个字符串列表:

names = ['Alice', 'Bob', 'Charlie']

我希望使用某个函数foo将所有这些字符串与特定的小写字符串进行比较:

map(lambda name: foo('carol', str.lower(name)), names)

有没有办法改变foo接受在foo评估之前评估的可调用bar?所以我可以这样写:

map(partial(foo, 'carol', str.lower), names)  # foo sees the name in lowercase

2 个答案:

答案 0 :(得分:3)

这就是他们为装饰师做的!看看装饰器,小写的所有参数都传递给某个函数:

 def lower_args(func):
   @functools.wraps(func)
   def _wrapper(*args, **kwargs):
     l_args = map(str.lower, args)
     l_kwargs = {(name, str.lower(value)) for (name, value) in kwargs}

     return func(*l_args, **l_kwargs)
   return _wrapper

像这样使用:

@lower_args
def foo(a, b, c):
  #and your code goes here

要执行您想要的操作,请稍微更改语法

def to_lower(mod_func):
  def deco(func):
    @functools.wraps(func)
    def _wrapper(*args, **kwargs):
      return func(*map(mod_func, args), {(k, mod_func(v)) for (k,v) in kwargs})
    return _wrapper
  return deco

用过:

@to_lower(my_function)
def foo(a, b, c):
  #your code goes here

答案 1 :(得分:2)

这样做的pythonic方法就是使用生成器表达式。您使用names的位置,而是放置:

(name.lower() for name in names)

将根据您的需要对容器进行迭代(“懒惰”)进行评估。