如果你同意重写内置组件__导入__
和一个简单的正则表达式来转换没有paren的print语句,然后您可以执行以下操作。请注意,这实际上并没有更改任何文件,只是当您导入它们时,它会将代码读入字符串,调整该字符串,然后将修复的代码发送给编译器/导入器
进口再进口导入系统如果sys.version_info>=(3,0):导入lib2to3从lib2to3导入main,重构导入操作系统导入类型导入内置程序导入系统导入importlib缓存={}prevImport=内置__导入__def customImport(路径、*args、**kwargs):#打印(路径、参数、夸格斯)尝试:return导入(路径+“.py”)除:return prevImport(路径,*args,**kwargs)def重新加载(文件名):fimport(文件名.__file__,forceReload=True)def-fimport(文件名,forceReload=False):文件名=os.path.abspath(文件名)modulePath=os.path.splitext(os.path.basename(文件名))[0]如果文件名在缓存中而不是forceReload:execval,modifyTime,module=缓存[文件名]如果modifyTime==os.path.getmtime(文件名):返回模块f=打开(文件名)text=f.read()+“\n”p=重新编译(“打印”)res=[]curI=0对于p.finditer中的m(文本):i=米开始()res.append(文本[curI:i])curI=ipieceTmp=text[i:].split(“\n”)[0]piece=文本[i:].split(“\n”)[0].splot(“#”)[0]pieceAfter=件[len('打印'):].strip()if pieceAfter[0]!='(':resLine=“print”+“(”+pieceAfter+“)”+“\n”res.附件(resLine)其他:res.append(件Tmp)curI+=长度(个Tmp)+1text=“”.join(res)f.关闭()'''#如果需要,此代码可以运行lib2to3,但仅用于替换不需要的打印#fixes=已排序(lib2to3.refactor.get_fixers_from_package('lib2to5.fixes'))fixes=['lib2to3.fixes.fix_print']rt=lib2to3.main。StdoutFactoringTool(修复,{},[],False,False)res=str(rt.refactor_string(文本,名称=模块路径))'''res=文本res=编译(res,'<string>','exec')模块=类型。ModuleType(模块路径)模块__file__=文件名cache[文件名]=(res,os.path.getmtime(文件名),模块)exec(res,模块.__dict__)返回模块内置组件__import__=自定义导入importlib.reload=重新加载
如果您将此代码保存到,比如说,patimport.py,那么假设我有一个名为juniper.py的文件:
定义哇(a):打印
现在,如果我想从python3调用juniper.py,我可以这样做
导入patiimport进口杜松子杜松子哇(“豆子”)
它将运行:)
这可能会更快,更像典型的带有缓存和日志记录等功能的导入,但我还不清楚pyc文件是如何生成的以及何时生成的。c插件也可能存在一些边缘情况,我不确定。因此,请随意提出改进建议,但至少这是一个概念证明。我认为您应该能够实际调整解释器输入和当前文件的值,但我现在正在处理这个问题。
此外,从技术上讲,这可以导入任何python2文件(2to3修复xrange、print等),如果这些文件导入其他python2文件,它们也会被转换,因为这会覆盖每个人使用的导入。您还可以实现任意操作符重载,需要静态类型,实际上需要大括号,从技术上甚至可以从其他语言导入代码,或者使用这个导入来更改python。但我离题了