如果我写
ls *.txt
Run Code Online (Sandbox Code Playgroud)
放入 IPython 笔记本中的单元格中,然后它会正确执行。但是,如果我尝试使用 转换单元格TransformerManager().transform_cell,则不会发生任何事情,并且会得到无效的 Python 语法:
>>> from IPython.core.inputtransformer2 import TransformerManager
>>> import ast
>>> TransformerManager().transform_cell('ls *.txt')
'ls *.txt\n'
>>> ast.parse('ls *.txt\n')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/ignoring_gravity/miniconda3/envs/tmp/lib/python3.8/ast.py", line 47, in parse
return compile(source, filename, mode, flags,
File "<unknown>", line 1
ls *.txt
^
SyntaxError: invalid syntax
Run Code Online (Sandbox Code Playgroud)
有没有办法以返回有效 Python 代码的方式转换 automagics?没有 automagic 的等效代码将转换如下:
>>> TransformerManager().transform_cell('!ls *.txt')
"get_ipython().system('ls *.txt')\n"
Run Code Online (Sandbox Code Playgroud)
我正在寻找的是一种无需运行代码即可检测自动魔术的方法
Automagics 是正在运行的内核的一项功能,而不是语法。例如,cd它本身就是一个有效的 automagic,除非它被 Python 名称遮盖,或者就此而言,如果它%automagic被禁用。
In [1]: cd\n/home/wja\n\nIn [2]: cd = \'CD\'\n\nIn [3]: cd\nOut[3]: \'CD\'\n\nIn [4]: del cd\n\nIn [5]: cd\n/home/wja\n\nIn [6]: %automagic 0\n\nAutomagic is OFF, % prefix IS needed for line magics.\n\nIn [7]: cd\nTraceback (most recent call last):\n File "<ipython-input-7-9c6465b4471e>", line 1, in <module>\n cd\nNameError: name \'cd\' is not defined\nRun Code Online (Sandbox Code Playgroud)\n在幕后,据我了解,当一个单元抛出某些错误(如SyntaxError或 )时NameError,它会被发送到预过滤器,如果它可以转化为魔法,它会被预过滤器捕获AutoMagicChecker并进行转化。我的理解主要基于\xc2\xa0这个关于 IPython GitHub 问题的评论:
\n\n输入变压器是逐行应用的,但预过滤器仅在代码运行时应用。因此,“无效”[无效行]会触发执行尝试,然后预过滤器介入并可能将其转换为有效代码。
\n
——托马斯·克鲁弗,2015 年 7 月 11 日
\n现在,如果您确实有正在运行的内核,则可以使用预过滤器,如下所示:
\nIn [1]: ip = get_ipython() # The running kernel\n\nIn [3]: source = ip.prefilter(\'cd\') # Transform\n\nIn [4]: source\nOut[4]: "get_ipython().run_line_magic(\'cd\', \'\')"\n\nIn [5]: exec(source) # Run, just to prove it works\n/home/wja\nRun Code Online (Sandbox Code Playgroud)\n或者,还有很长的路要走:
\nIn [2]: from IPython.core.splitinput import LineInfo\n\nIn [3]: line_info = LineInfo(\'cd\') # Parse\n\nIn [4]: ip = get_ipython()\n\nIn [5]: ip.prefilter_manager.checkers # List of prefilters\nOut[5]:\n[<EmacsChecker(priority=100, enabled=False)>,\n <MacroChecker(priority=250, enabled=True)>,\n <IPyAutocallChecker(priority=300, enabled=True)>,\n <AssignmentChecker(priority=600, enabled=True)>,\n <AutoMagicChecker(priority=700, enabled=True)>,\n <PythonOpsChecker(priority=900, enabled=True)>,\n <AutocallChecker(priority=1000, enabled=True)>]\n\nIn [6]: for checker in ip.prefilter_manager.checkers:\n ...: handler = checker.check(line_info)\n ...: if handler: # Find the first one that matches\n ...: break\n ...:\n\nIn [7]: handler\nOut[7]: <IPython.core.prefilter.MagicHandler at 0x7f01e8ccc7f0>\n\nIn [10]: handler.handle(line_info) # Transform\nOut[10]: "get_ipython().run_line_magic(\'cd\', \'\')"\nRun Code Online (Sandbox Code Playgroud)\n
| 归档时间: |
|
| 查看次数: |
166 次 |
| 最近记录: |