More functional python
我想写一些CPS代码高级函数。他们应该获取一个函数代码,将其封装在对象中,并添加组合这些对象的方法。
像这样:
1 2 3 4 | myFunction=MyFunction( a = b+c print(c) return a) |
但是匿名函数只有一个pythonic表达式-lambda语句。它不太适合。
python是一种强大的语言,它有不同的表达式:decorator、eval等。有没有一种好的方法来编写匿名函数,就像上面提到的例子中那样?
另一种方法是扩展lambda表达式,使用特殊函数(如单元绑定和返回),以及其他用于单行编写复杂表达式的高阶函数。
主要目的是创建自定义的抛出控件表达式。
1 2 3 4 5 6 7 8 9 10 11 12 | class TimeoutExpression: def __init__(self,name,function,timeout): ... def eval(self): """ eval functions, print result and error message if functions failed to calculate in time""" ... def andThen(self,otherExpression): """ create complex sequential expression" ... def __call__(self): ... |
其使用方法如下:
1 2 3 | TimeoutExpression( time consuming calculation ).andThen( file object access).andThen( other timer consuming calcualtion ) |
创建自定义控制流构造的最佳python惯用方法是什么?
我读过讨论:如何在不命名的情况下在Python中创建匿名函数?有人提到了几种使用相同方法的决策:从三重引用字符串生成函数。它看起来很笨重,但行为绝对正确。这是目前设计的最佳方法吗?
更新:
我被告知没有问题,Python允许您在任何上下文中使用def。我假设我的Python体验欺骗了我,并尝试在建议的任何范围内使用def。我有个错误。在任何上下文中,我应该如何准确地放置def?
1 2 3 4 5 6 7 8 9 10 | def compose(f): return lambda k: lambda x: f(k(x)) test = compose( def sqr(x) : print ("sqr"+str(x)) return x*x return sqr) ( def x2(x): print("x2"+str(x)) return x*2 return x2 ) |
错误:
1 2 3 4 5 6 | Traceback (most recent call last): File"<input>", line 1, in <module> File"anonFunction.py", line 4 test = compose( def sqr(x) : ^ SyntaxError: invalid syntax |
使用lambda的w.r.t python没有优势。lambda函数和匿名函数通常用于简单函数,如果需要更复杂的多行函数,则编写命名函数更具可读性。
因为函数是第一类对象,所以您可以简单地定义它,将它赋给一个变量,然后使用它并传递它。除非另外需要一个可以选择lambda的一次性简单函数,否则命名函数是有利的。尽管如此,在从不完全的Python中使用lambda。
回到你的例子,
1 2 3 4 | myFunction=MyFunction( a = b+c print(c) return a) |
在python中,编写它的方式与
1 2 3 4 | def MyFunction: a =b + c print c return a |
然后把它作为
---可读性计数。
我有一个黑客——这确实是唯一合适的术语——使用嵌套函数,它提供了多行lambda可能提供的某种功能。您可以在这里查看我的Github存储库。
基本上,它允许你做如下的事情:
1 2 | fibonacci = f('result = t(a-1)+t(a-2) if a>2 else 1; return result') fibonacci(6) #Output: 8 |
或更多匿名函数:
1 2 | cube = f('result = a**3; return result')(4) print(cube) #Output: 64 |
这种黑客有明显的局限性;例如,我还没有找到一种实现更复杂的缩进结构的方法,比如
在python中,使用
限制
python中没有多行lambda:为什么不呢?
但是,名称并不重要。您可以约定,您的每个"匿名"函数都将以名称
1 2 3 4 5 6 7 8 9 | y = 5 def anon(x): return x + y # note"closure" over the current value of y myFunction = anon # if you really care, you can erase all evidence of name"anon" anon.__name__ = '' # wipe the record of original name"anon" del(anon) # unbind the name"anon" |
因此,对于函数式编程,python可以创建一流的函数对象,传递它们,等等。python不能做的一件事是创建一个没有名称的复杂函数对象,但实际上没有理由这么做。