我不知道是否可以使打印函数(不改变所有地方的语法)像Python 2及其早期版本那样运行。
因此,我的语句如下:
print "Hello, World!"
我希望这种语法可以在Python 3中工作。我尝试导入six
库,但那并没有起作用(仍然是语法错误)。
因此,我的语句如下:
print "Hello, World!"
我希望这种语法可以在Python 3中工作。我尝试导入six
库,但那并没有起作用(仍然是语法错误)。
from __future__ import print_function
print
语句的支持,就像在Python 3中一样,并且您可以使用随Python 2一起提供的print()
函数。但是six
只能帮助桥接同时考虑Python 2和3的代码; 这包括首先用print()
函数替换print
语句。您可能想阅读Porting Python 2 Code to Python 3 howto; 它将告诉您更多类似的from __future__
导入,以及介绍诸如Modernize和Futurize等工具,可帮助自动修复Python 2代码以在Python 2和3上运行。print
代码替换为 Python 3:Find:
(print) (.*)(\n)
Replace with:
$1($2)$3
我创建了这个文件,python2.py:
#!python3
print 5
line 3
print 5 ^
SyntaxError: Missing parentheses in call to 'print'
因此,你可以通过终端来进行转换,像这样:
这是重要的命令
$ 2to3 -w home/path_to_file/python2.py
-w参数将会写入文件,如果你只想查看未来的更改而不应用它们,只需运行它而不加-w参数。 运行后,它会显示类似于以下内容:
root: Generating grammar tables from /usr/lib/python2.7/lib2to3/PatternGrammar.txt
RefactoringTool: Refactored Desktop/stackoverflow/goto.py
--- Desktop/stackoverflow/goto.py (original)
+++ Desktop/stackoverflow/goto.py (refactored)
@@ -1,3 +1,3 @@
#!python3
-print 5
+print(5)
RefactoringTool: Files that were modified:
文件将会是这个样子:
#!python3
print(5)
builtins.__import__
并使用简单的正则表达式来转换没有括号的打印语句,那么你可以按照以下步骤操作。请注意,这实际上不会更改任何文件,只是在导入它们时将代码读入字符串中,调整该字符串,然后将修复后的代码发送给编译器/导入器。import re
import sys
if sys.version_info >= (3, 0):
import lib2to3
from lib2to3 import main, refactor
import os
import types
import builtins
import sys
import importlib
cache = {}
prevImport = builtins.__import__
def customImport(path, *args, **kwargs):
#print (path, args, kwargs)
try:
return fimport(path + ".py")
except:
return prevImport(path, *args, **kwargs)
def reload(filename):
fimport(filename.__file__, forceReload=True)
def fimport(filename, forceReload=False):
filename = os.path.abspath(filename)
modulePath = os.path.splitext(os.path.basename(filename))[0]
if filename in cache and not forceReload:
execval, modifyTime, module = cache[filename]
if modifyTime == os.path.getmtime(filename):
return module
f = open(filename)
text = f.read() + "\n"
p = re.compile("print")
res = []
curI = 0
for m in p.finditer(text):
i = m.start()
res.append(text[curI:i])
curI = i
pieceTmp = text[i:].split("\n")[0]
piece = text[i:].split("\n")[0].split("#")[0]
pieceAfter = piece[len('print'):].strip()
if pieceAfter[0] != '(':
resLine = "print" + "(" + pieceAfter + ")" + "\n"
res.append(resLine)
else:
res.append(pieceTmp)
curI += len(pieceTmp)+1
text = "".join(res)
f.close()
'''
# this code can run lib2to3 if you want but just for replacing prints that is not needed
#fixes = sorted(lib2to3.refactor.get_fixers_from_package('lib2to3.fixes'))
fixes = ['lib2to3.fixes.fix_print']
rt = lib2to3.main.StdoutRefactoringTool(fixes, {}, [], False, False)
res = str(rt.refactor_string(text, name=modulePath))
'''
res = text
res = compile(res, '<string>', 'exec')
module = types.ModuleType(modulePath)
module.__file__ = filename
cache[filename] = (res, os.path.getmtime(filename), module)
exec(res, module.__dict__)
return module
builtins.__import__ = customImport
importlib.reload = reload
def wow(a):
print a
import pastimport
import juniper
juniper.wow("bean")
这将可以运行 :)
这可能会更快,并且更像典型的导入方式,具有缓存和日志记录等功能,但我还不太明白pyc文件是如何生成的,以及何时生成。对于c插件等边缘情况,我也不确定。因此,欢迎提出改进建议,但至少这是一个概念验证。我认为您应该能够实际调整解释器输入和当前文件的值,但我正在尝试。
技术上,这也允许您导入任何python2文件(2to3修复xrange,print等),如果这些文件导入其他python2文件,则它们也会被转换,因为这覆盖了每个人都使用的导入方式。您还可以实现任意操作符重载,要求静态类型,实际上需要花括号,甚至可以使用此单个导入从其他语言导入代码或更改Python。但我跑题了。
print(1,2)
上运行2to3,你会发现在Python 3代码上运行2to3是不安全的。 - user2357112(1, 2)
(在同一个文件中有print a
),这正是Python3所做的。而且像print(1,2)\nprint('games', end='')
这样的东西也可以正常工作。 - Phylliida#!/usr/bin/python3.8 -i
import subprocess, shlex, sys, readline, traceback
def excepthook(exctype, value, tb):
if exctype is SyntaxError:
index = readline.get_current_history_length()
command = readline.get_history_item(index)
if command.find("print") != -1:
sp = command.split("print")[1]
new = "print" + "(" + sp + ")"
eval(new)
else:
traceback.print_exception(exctype, value, tb)
sys.excepthook = excepthook