在shell中轻松运行Python!神奇,但从不神秘。
项目描述
pyp
在shell中轻松运行Python!神奇,但从不神秘。
安装
运行 pip install pypyp
(注意额外的"yp"!)
pyp需要Python 3.8或更高版本。
工作原理
pyp将静态分析输入代码以检测未定义的变量。根据它发现的内容,它将按需转换输入代码的AST。然后我们编译并执行结果,或者如果使用--explain
,将AST反解析为源代码。
示例
本节将向您介绍使用pyp的细节,并希望满足您对许多常用shell工具的需求。要查看速查表/tldr,请运行pyp --help
。
pyp可以轻松地应用于输入的每一行。
只需使用一个魔法变量x
、l
或line
来引用当前行。
# pyp like cut
ls | pyp 'x[:3]'
ps x | pyp 'line.split()[4]'
pyp也可以轻松地将Python代码应用于整个输入。
使用魔法变量lines
表示去除尾部的行的列表,或使用stdin
表示sys.stdin
。
# pyp like wc -c
cat /usr/share/dict/words | pyp 'len(stdin.read())'
# pyp like awk
seq 1 5 | pyp 'sum(map(int, lines))'
pyp会自动导入您使用的模块。
# pyp like sh
echo echo echo | pyp 'subprocess.run(lines[0], shell=True); pass'
# pyp like jq
curl -s 'https://api.github.com/repos/hauntsaninja/pyp/commits?per_page=1' | pyp 'json.load(stdin)[0]["commit"]["author"]'
# pyp like egrep
cat /usr/share/dict/words | pyp 'x if re.search("(p|m)yth", x) else None'
对于collections
、math
、itertools
、pathlib.Path
、pprint.pp
,pyp会自己解决,即使您没有使用限定名。
# pyp like bc
pyp 'sqrt(5)'
# pyp like ${x##*.}
ls | pyp 'Path(x).suffix'
pyp可以使用魔法变量i
、idx
或index
提供对循环索引的访问。
# pyp like line numbers
cat setup.py | pyp 'f"{idx+1: >3} {x}"'
请注意,到目前为止,您不需要调用print
!
默认情况下,pyp 会打印代码中的最后一个表达式——除非它评估为 None
(或最后一个语句是 pass
)。您始终可以显式调用 print
,在这种情况下,pyp 将不会打扰您。
# pyp like grep
cat /usr/share/dict/words | pyp 'x if "python" in x else None'
cat /usr/share/dict/words | pyp 'if "python" in x: print(x); "this will not be printed"'
pyp 会尝试智能地打印字典和可迭代对象。
这使得 pyp 的输出更容易与 shell 工具组合。再次强调,显式打印将停止这种魔法,但如果您希望重新启用,pyp 提供了 pypprint
函数。
# pyp like tail
ls | pyp 'lines[-10:]'
# pyp like sort
ls | pyp 'sorted(lines)'
ls | pyp 'print(f"Sorting {len(lines)} lines"); pypprint(sorted(lines))'
# pyp like sort | uniq
ls | pyp 'sorted(set(lines))'
pyp 允许您在处理输入前后运行 Python 片段。
注意,如果您遇到分号问题并希望换行(而不用在 shell 中使用多行字符串),只需向 pyp 传递另一个字符串即可。您也可以始终将 pyp 管道到 pyp!
# pyp like anything!
ps aux | pyp -b 'd = defaultdict(list)' 'user, pid, *_ = x.split()' 'd[user].append(pid)' -a 'del d["root"]' -a 'd'
pyp 可以很神奇,但不必神秘!
使用 --explain
或 --script
,pyp 将输出一个与它将要运行的脚本等效的输出。这也可以作为更复杂脚本的 useful 起始点。
pyp --explain -b 'd = defaultdict(list)' 'user, pid, *_ = x.split()' 'd[user].append(pid)' -a 'del d["root"]' -a 'd'
#!/usr/bin/env python3
from collections import defaultdict
from pyp import pypprint
import sys
d = defaultdict(list)
for x in sys.stdin:
x = x.rstrip('\n')
(user, pid, *_) = x.split()
d[user].append(pid)
del d['root']
if d is not None:
pypprint(d)
如果您的命令遇到异常,pyp 将将跟踪信息重新构造到生成的代码中。
pyp 是可配置的。
将环境变量 PYP_CONFIG_PATH
指向一个包含以下内容的文件,例如
import numpy as np
import tensorflow as tf
from pipetools import *
def p95(data):
return np.percentile(data, 95)
class PotentiallyUsefulClass: ...
当尝试定义未定义的名称时,pyp 会将此文件作为可能的定义来源进行静态分析。这意味着如果您没有使用 tf
,我们不会导入 tensorflow
!当然,--explain
将显示确切运行的内容(以及因此没有运行的内容!)
pyp --explain 'print(p95(list(map(float, stdin))))'
#!/usr/bin/env python3
import sys
import numpy as np
def p95(data):
return np.percentile(data, 95)
stdin = sys.stdin
print(p95(list(map(float, stdin))))
注意,在配置中从类似 pipetools 的库中导入内容可以允许您达到高级别的语法糖
seq 1 110 | pyp 'lines > foreach(int) | where(X > 100) | group_by(X % 3) | sort_by(X[0])'
如果使用通配符导入,如果存在未定义的名称,我们需要导入这些模块,尽管在 happy path 中我们跳过了这一步。如果这对您很重要,那么请绝对不要在您的配置中使用 from tensorflow import *
!
pyp 允许您配置自己的魔法!
如果配置文件中的定义依赖于魔法变量,pyp 将按照有意义的方式进行替换。例如,将以下内容放入您的配置...
n = int(x)
f = x.split()
j = json.load(stdin)
import pandas as pd
csv = pd.read_csv(stdin)
...以使 pyp 对您的自定义用例更加便捷
ps | pyp 'f[3]'
cat commits.json | pyp 'j[0]["commit"]["author"]'
< cities.csv pyp 'csv.to_string()'
我有问题!
有关文档和示例,请参阅 FAQ。如果这不能回答您的问题,请提出一个 issue!
相关项目
Pyed Piper 即在提示符中的 Python 力量
pypyp 从这里获得了灵感(以及命令名称!)
Pyed Piper 已经死亡十年,并且仅适用于 Python 2,当 pypyp 被编写时;它最近似乎被复活了。Pyed Piper 比 pypyp 靠近常规 Python 语法和 API。特别是,Pyed Piper 强调在 Python 中进行管道,类似于您可以将 pipetools
与上面的配置示例中的 pypyp
结合起来的方式。
Pyped
Pyped 非常相似;相似到我不知道它时,我可能不会编写 pyp。但很高兴我没有,因为 Pyped 不执行我们做的 AST 内省和操作。这意味着
- Pyped 依赖于您传入标志来告诉它做什么,而 pyp 可以从输入中明确推断意图。
- 它不提供简单的自动打印,也不提供智能打印可迭代对象和字典。
- 它硬编码了一个导入列表,并在您的系统上安装了一些库。此项目的自动导入适用于您使用的任何库。
- 它没有像
--explain
/--script
这样的功能。
然而,
- 它有一些便利之处,例如输入的正则表达式分割,您需要自己在这里完成。
- 它支持 Python 2 和 Python 3 的早期版本。
- 它已经存在很长时间了。
piep / spy / pyfil / pythonpy / oneliner
自从编写了 pyp,发现比我想的还有更多替代方案 :-) 一些快速笔记
- 其中大多数依赖于用户传递标志,例如 Pyped。
- 其中大多数在自动打印方面存在限制,例如只能自动打印单个表达式,或者不很好地处理可迭代对象和字典。
- 其中一些提供了进程内命令链的定制语法,这可能会很方便。
- 其中一些专门支持JSON输入或运行shell命令等。
- 其中一些通过自定义行/文件/流对象以有趣的方式暴露输入。
- 其中一些在错误处理方面具有更高级的选项(尽管它们没有一个像pyp那样出色的回溯)。
- 它们都没有像pyp那样强大的配置功能。
- 它们都没有像
--explain
这样的功能。
无论如何,我已经按照个人偏好的顺序列出了上述项目。
mario
mario
是一种对使用Python进行shell处理的改进方案。它不使用未定义名称检测,而是依赖于可插拔的子命令系统。虽然子命令可能比 pyp 更冗长,但 mario
通过自动应用函数和自定义命令链语法来弥补一些不足。结果可能感觉有点 DSL 风格,而 pyp 则试图感觉非常接近编写 Python。
考虑使用 mario
如果
- 您发现自己正在连接长序列的 pyp 命令,并希望能够在一个进程内进行命令链。
- 您经常需要重复使用复杂的 pyp 命令,或者进行大量的特定领域shell处理,您希望能够用单个命令重复使用。
- 您希望能够轻松地使用异步函数。
考虑 pyp 如果
- 您希望最小化快速且简单的事情的按键次数。
- 您想要一个最小化和轻量级的工具,感觉非常接近 Python。您不想记住命令。
- 您愿意使用 Python 库来完成特定领域的繁重工作,以便轻松进行命令链或语法糖。您不介意(或想要能够)通过
--script
回退到脚本以处理复杂性。
xonsh
xonsh
是一种其语言是Python超集的shell;这更加雄心勃勃,与 pyp 很不同。pyp 对于单行管道用例更容易使用,但如果您需要在shell中使用更多Python,请查看 xonsh
。
awk
如果 awk
对您适用,您是如何来到这里的?
项目详情
下载文件
下载适用于您的平台的文件。如果您不确定选择哪一个,请了解更多关于 安装包 的信息。
源分发
构建分发
pypyp-1.2.0.tar.gz 的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | d1571ed626bd65686248be7f7332dd750f413b15de1ae80ac1ddb353bd34486d |
|
MD5 | b615f787c6914e425c6c244fb9bb6354 |
|
BLAKE2b-256 | 88af8c8a089edfc8690fdc00e404386d090aea1a16acf0adfffdc361cd699de6 |
pypyp-1.2.0-py3-none-any.whl 的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 45e2a0fbe5b7b5bb0be7e95bcb5b23d43ddae8c561410c9c336e6773005c70b1 |
|
MD5 | 5d5e6e42cf292167d130cd54a6894388 |
|
BLAKE2b-256 | e06c6a9eac381dd1f0d2e878ad6213fca24cfe5b3846db46b26d620301ac7624 |