2015-03-06 14 views
5

Mi chiedo se la funzione di stampa può essere fatta funzionare (senza modificare la sintassi in ogni punto) come in Python 2 e precedenti.In python 3.x fare lavori di stampa come in python 2 (come istruzione)

Così ho la dichiarazione del tipo:

print "hello world" 

E mi piace che la sintassi di lavorare in Python 3. Ho provato ad importare la libreria six, ma che non ha fatto il trucco (ancora un errore di sintassi).

+1

Lol, voglio la stessa identica cosa. Mi piace tutto di python 3 tranne la dichiarazione di stampa – gunit

risposta

4

No, non è possibile. L'istruzione print è scomparsa in Python 3; il compilatore non lo supporta più.

È può far print() lavoro come una funzione in Python 2; mettere questo nella parte superiore di ogni modulo che utilizza print:

from __future__ import print_function 

Questo eliminerà il supporto per il print dichiarazione in Python 2, proprio come si va in Python 3, ed è possibile utilizzare il print() function that ships with Python 2.

six può solo aiutare a eseguire il bridge del codice scritto con in mente sia Python 2 che 3; che include la sostituzione delle dichiarazioni print con le funzioni print()prima.

Probabilmente si desidera leggere il Porting Python 2 Code to Python 3 howto; ti dirò circa più di tali importazioni from __future__ pure, così come introdurre strumenti come Modernize e Futurize che possono aiutare ad automatizzare il fissaggio Python 2 del codice di lavorare su entrambi Python 2 e 3.

+1

Questo è un peccato: ho bisogno di eseguire codice fornito da una terza parte e non mi piace davvero scavalcare tutto il codice che cambia tutte quelle stampe: /. (Quello che descrivi qui è l'opposto del mio problema: io lavoro in python 3, ma ho bisogno di eseguire codice scritto da persone che lavorano in python 2) – paul23

+1

@ paul23: scusa, strumento sbagliato. Dovresti provare a usare l'utilità ['2to3'] (https://docs.python.org/2/library/2to3.html) per sistemare automaticamente il codice Python 2. –

+0

@ paul23 se sei ** veramente ** interessato alle istruzioni di Python e alla meccanica delle parole chiave, potresti divertirti a leggere [questo] (http://mathamy.com/import-accio-bootstrapping-python-grammar.html) articolo. – OzTamir

2

È possibile utilizzare lo strumento 2to3 è un Automated Python 2 to 3 code translation, come ha detto @Martijn Pieters ♦ :), è possibile ottenere oltre un giro gettare il vecchio pitone e apportare le modifiche funzionano in Python 3, faccio un semplice esempio come questo:

ho creato questo file , python2.py:

#!python3 

print 5 

quando l'eseguo con Python lo dimostra chiaramente:

line 3 
    print 5  ^
SyntaxError: Missing parentheses in call to 'print' 

modo, è possibile trasformare tramite terminale come questo:

Questo è il COMAND importante

$ 2to3 -w home/path_to_file/python2.py 

-w parametro scriverà il file, se si desidera vedere solo le modifiche future senza applicarle, basta eseguirlo senza -w. dopo l'esecuzione esso mostrerà qualcosa di simile

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: 

e il file sarà simile:

#!python3 

print(5) 
-1

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

+1

Questo cercherà di eseguire 2to3 su tutto, indipendentemente dal fatto che sia in realtà un codice Python 2. – user2357112

+0

Bene 2to3 funziona bene con il codice python3 (non apporta modifiche), ma sì, sono d'accordo che ci sono molti casi limite (come .pyd) che questo deve tenere conto. È abbastanza facile da fare perché puoi semplicemente chiamare la funzione di importazione originale, ma non ho aggiunto i controlli qui. Idealmente dovrebbe generare anche file .pyc. Sentiti libero di suggerire modifiche. – Phylliida

+0

Prova a eseguire 2to3 su 'print (1, 2)', e vedrai che non è sicuro eseguire 2to3 sul codice Python 3. – user2357112