将任何python文件转换为一行代码。
onelinerizer的Python项目详细描述
单线性izer
将任何python文件转换为具有相同功能的单行代码。
不允许换行。也不允许使用分号。
live demo在onelinepy.herokuapp.com!
Presentation at PyCon 2016,和slide deck。
用户安装和使用
从pypi通过pip
安装:
$ pip install onelinerizer
使用命令行函数或python模块:
$ echo"def f(x):\n print x\nf(4)" > sandbox.py $ onelinerizer sandbox.py --debug $ onelinerizer sandbox_ol.py
fromonelinerizerimportonelinerizeonelinerize("def f(x):\n print x\nf(4)")
示例
之前:
x=3y=4print(x<y<5)
之后:
(lambda__builtin__:(lambda__print,__y,d:[[__print(d.x<d.y<5)ford.yin[(4)]][0]ford.xin[(3)]][0])(__builtin__.__dict__['print'],(lambdaf:(lambdax:x(x))(lambday:f(lambda*args:y(y)(*args)))),type('StateDict',(),__builtin__.__dict__)()))(__import__('__builtin__'))
这一行看起来很复杂,因为我们需要一些技巧来导入print函数并支持一些更复杂的特性(如while
和if
)所需的技巧。不过,对于像这个这样简单的程序,您可以认为它是这样工作的:
(lambdax:(lambday:print(x<y<5))(4))(3)
之前:
deff(x):returnx+5printf(13)
之后:
(lambda__builtin__:(lambda__print,__y,d:[__print(d.f(13))ford.fin[(lambdax:[(d.x+5)ford.xin[(x)]][0])]][0])(__builtin__.__dict__['print'],(lambdaf:(lambdax:x(x))(lambday:f(lambda*args:y(y)(*args)))),type('StateDict',(),__builtin__.__dict__)()))(__import__('__builtin__'))
…或者,如果你想考虑更简单的事情:
(lambdaf:print(f(13)))(lambdax:x+5)
之前:
defguess_my_number(n):whileTrue:user_input=raw_input("Enter a positive integer to guess: ")iflen(user_input)==0ornotuser_input.isdigit():print"Not a positive integer!"else:user_input=int(user_input)ifuser_input>n:print"Too big! Try again!"elifuser_input<n:print"Too small! Try again!"else:print"You win!"returnTrueguess_my_number(42)
之后:
(lambda__builtin__:(lambda__print,__y,d:[(lambda___:None)(d.guess_my_number(42))ford.guess_my_numberin[(lambdan:[(__y(lambda__this:(lambdad:(lambda__after:[(lambda__after:(lambda___:__after(d))(__print('Not a positive integer!'))if(d.len(d.user_input)==0or(notd.user_input.isdigit()))else[(lambda__after:(lambda___:__after(d))(__print('Too big! Try again!'))ifd.user_input>d.nelse(lambda__after:(lambda___:__after(d))(__print('Too small! Try again!'))ifd.user_input<d.nelse(lambda___:d.True)(__print('You win!')))(lambdad:__after(d)))(lambdad:__after(d))ford.user_inputin[(d.int(d.user_input))]][0])(lambdad:__this(d))ford.user_inputin[(d.raw_input('Enter a positive integer to guess: '))]][0]ifd.Trueelse__after(d))(lambdad:None))))(d)ford.nin[(n)]][0])]][0])(__builtin__.__dict__['print'],(lambdaf:(lambdax:x(x))(lambday:f(lambda*args:y(y)(*args)))),type('StateDict',(),__builtin__.__dict__)()))(__import__('__builtin__'))
常见问题解答
天哪,为什么?
是的。我很抱歉。但另一方面,为什么不呢?
你不能用分号吗?
这将违背这项工作的精神。为什么要放弃一个完美的借口来滥用lambda functions、ternary expressions、list comprehensions,甚至偶尔滥用Y combinator?千万不要错过使用y组合的机会。
分析
输出程序大小
o(n)。没有代码是重复的,所以产生的单行代码在输入代码的大小上是线性的。
单行代码的运行时间
我没有理由相信得到的代码,不管多么荒谬,都比原来的代码慢得多。由于while循环等是使用递归函数调用实现的,这会导致设置这些函数调用的更多开销,因此常量因子可能有点不好。
提示
单行代码往往包含许多嵌套的lambda;如果太多,python将拒绝运行它。
$ python main_ol.py s_push: parser stack overflow MemoryError
这可以用pypy修复。
$ pypy main_ol.py
但是,由于使用递归实现循环和for循环,如果循环持续太长时间,则在运行时可能会遇到maximum recursion depth exceeded
错误。
要解决这个问题,您可以放置
importsyssys.setrecursionlimit(new_limit)
在原始的python代码中。(OneLinerizer不会为您放入此命令。)
未实现
- 从foo import*
未决问题
- 使用
- 收益率
开发人员安装和测试
$ git clone https://github.com/csvoss/onelinerizer $ cd onelinerizer $ python -m onelinerizer .setup.py setup.py $ python setup.py test
要安装本地模块:
$ pip install .
进一步阅读
- Lambda calculus
- Fixed-point combinator
- StackOverflow关于函数式编程如何帮助掌握python的帖子
- On writing Python one-liners-类似的想法
- 向this StackOverflow post的作者大声喊叫,他似乎在做一个非常相似的项目