Se siete daccordo con prioritario builtins.__import__
e una semplice espressione regolare per convertire le istruzioni print che non lo fanno hai paren quindi puoi fare quanto segue. Si noti che questo non modifica qualsiasi file, proprio quando li si importa leggerà il codice in una stringa, tweak che stringa, quindi inviare il codice fisso al compilatore/importatore
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
Se si salva questo codice, per esempio, pastimport.py, allora diciamo che ho un po 'di file chiamato juniper.py:
def wow(a):
print a
Ora, se voglio chiamare juniper.py da python3, posso solo fare
import pastimport
import juniper
juniper.wow("bean")
E funzionerà :)
Probabilmente questo potrebbe essere più veloce e più simile alle importazioni tipiche con memorizzazione nella cache e registrazione e roba ma non capisco esattamente come e quando i file pyc sono ancora generati. Potrebbero esserci anche casi limite con plug-in c e non ne sono sicuro. Quindi sentiti libero di suggerire miglioramenti, ma almeno questa è una prova di concetto. Penso che dovresti essere in grado di modificare effettivamente gli input dell'interprete ei valori del file corrente, ma ora sto giocando con questo.
anche tecnicamente questo consente di importare qualsiasi tipo di file python2 (correzioni 2to3 xrange, stampa, etc.) e se tali file importare altri file python2 che verrà convertito troppo dal momento che questo sostituisce l'importazione tutti usano. È inoltre possibile implementare il sovraccarico dell'operatore arbitrario, richiedere la digitazione statica, richiedere effettivamente parentesi graffe e tecnicamente persino importare il codice da altre lingue o cambiare completamente Python con questa singola importazione. Ma sto divagando
Lol, voglio la stessa identica cosa. Mi piace tutto di python 3 tranne la dichiarazione di stampa – gunit