2015-02-08 65 views
0

我发现自己写了太多的这些:如何避免在Python中重复lambda样板?

upper = lambda c : c.upper() 
lower = lambda c : c.lower() 
foo = lambda a,b : a.foo(b) 

如何避免或至少减少这种样板?

是否(或不应该)有一个PEP允许传递/调用方法作为正常程序?

+4

为什么你需要这个?我不记得曾经使用过这种模式,我有经验。也许有更好的方法。 – 2015-02-08 20:53:08

+0

我不会打电话给样板;你唯一'重复使用'的是'lambda'关键字。你可以使用'operator.methodcaller()'或'functools.partial()',但是你不会在定义这些对象时保存任何字符。 – 2015-02-08 20:53:35

+1

一种方法是根本不使用它,不知道我明白了。 – 2015-02-08 20:53:40

回答

0

可以使用非绑定方法,而不是创建自己的函数。

在前两个示例中,您可能需要str.upperstr.lower。 (如果你需要支持超过str,你可以使用operator.methodcaller("upper")或类似,但要知道,这是几乎可以肯定是不好的设计决策同时处理strbytes对象以相同的代码!)

你的第三个例子比较复杂。如果您只关心单一类型的a对象,那么您可以指定它,它就像str示例(例如A.foo)一样工作。同样,如果b的值是恒定的并且提前知道,则可以使用operator.methodcaller("foo", b)获得一个可调用的值,该值对给定的a值调用a.foo(b),但如果b也是可变的,则该值无效。

如果您事先不知道a的类型或b,您确实需要坚持一个功能。如果你不喜欢的lambda表达式的样子,你可以使用常规def声明:

def foo(a, b): 
    return a.foo(b) 

如果这是你经常使用的东西,你可以写上methodcaller自己的变化,产生对需求的功能:

def my_methodcaller(method_name): 
    def inner(obj, *args, **kwargs): 
     return getattr(obj, method_name)(*args, **kwargs) 
    return inner 

然后,你会使用foo = my_methodcaller("foo")

4

我真的不知道你在解决什么问题。你只是改变你的方法从

'abc'.upper() 

upper('abc') 

它并没有真正获得你什么,实际上它是一个小的可读性。如果您使用的拉姆达的传递到其他方法key你可以做这样的事情

l = ['ab', 'Aa', 'ca'] 
sorted(l, key = str.upper) 

注意,我可以叫str.upper而无需定义一个lambda

2

如何避免或者至少最小化这样的样板?

只是不要使用它!或者更具体地说:

  • 使用c.upper()而不是upper(c)
  • 使用c.lower()而不是lower(c)
  • 使用a.foo(b)而不是foo(a, b)
+0

函数对象的优点是可以将它们存储在映射中并动态应用它们。 *有*用于他们的用例。 – 2015-02-08 21:02:48

+0

我同意,但他的例子,尤其是'a.foo(b)'的例子,表明他/她的目标是围绕使用古典意义上的方法,因为他/她似乎更喜欢“功能”方法。如果他/她的目标是以类似地图的方式应用方法,那么我认为我们有更好的建议,比如使用列表解析。 – 2015-02-08 21:07:55