Domanda

Sto cercando di utilizzare il modulo python-daemon. Fornisce la classe daemon.DaemonContext a demonizzare correttamente uno script. Anche se sono in primo luogo mira Python 2.6+, mi piacerebbe mantenere la compatibilità alla versione 2.4.

Python 2.5 supporta l'importazione contesti da futuro , ma Python 2.4 non ha tale struttura. Ho pensato che potevo appena pescato qualunque errore il con rilanci economici e attivare e disattivare manualmente il contesto per 2.4, ma non riesco a prendere lo SyntaxError sollevato.

C'è un modo per raggiungere questo obiettivo a corto di controllare in modo esplicito la versione interprete? Di seguito è riportato l'essenza di quello che sto cercando di fare e il problema che sto ottenendo. In Real Life non ho il controllo della classe del contesto, quindi ha bisogno di lavoro senza pressare la classe originale, cioè non come queste idee.

Nevermind se Python 2.4 non è possibile eseguire python-daemon; Mi piacerebbe almeno come al grado di catturare l'errore e attuare un ripiego o qualcosa del genere.

Grazie per l'aiuto.

#!/usr/bin/python2.4
from __future__ import with_statement
# with_statement isn't in __future__ in 2.4.
# In interactive mode this raises a SyntaxError.
# During normal execution it doesn't, but I wouldn't be able to catch it
# anyways because __future__ imports must be at the beginning of the file, so
# that point is moot.


class contextable(object):
    def __enter__(self):
        print('Entering context.')
        return None
    def __exit__(self, exc_type, exc_val, exc_tb):
        print('Exiting context.')
        return False

def spam():
    print('Within context.')

context = contextable()

try:
    with context: # This raises an uncatchable SyntaxError.
        spam()
except SyntaxError, e: # This is how I would like to work around it.
    context.__enter__()
    try:
        spam()
    finally:
        context.__exit__(None, None, None)
È stato utile?

Soluzione

SyntaxError viene diagnosticata dal compilatore Python come si compila - si sta presumibilmente cercando di "catturare" dal codice che viene compilato come parte dello stesso modulo (ad esempio, è quello che si sta facendo nel vostro codice di esempio) , così naturalmente non funzionerà -. tua "recupero" il codice non è stato ancora compilato (a causa di compilazione ha terminato senza successo) in modo che non può prendere nulla

È necessario garantire il codice che potrebbe avere un errore di sintassi viene compilato dopo che il codice cattura - sia messo in un modulo separato che si importa nella clausola try, o in una stringa si compile con il built-in con quel nome (in seguito sarà possibile eseguire il bytecode risultante dalla chiamata compile, se termina con successo).

Né possibilità sembra buono per i vostri scopi, credo. Ho il sospetto che l'utilizzo di due moduli separati (e probabilmente raccogliendo tra di loro a seconda del "fa questo compilazione" di controllo, ma un controllo di versione suona molto più pulito per me) è l'unica soluzione "pulita", purtroppo.

Modifica : ecco come microbenchmark try / tranne contro controlli di versione:

$ python2.4 -mtimeit 'try:
  compile("with x: pass", "", "exec")
except SyntaxError: x=1
else: x=2'
100000 loops, best of 3: 10.8 usec per loop
$ python2.6 -mtimeit 'try:
  compile("with x: pass", "", "exec")
except SyntaxError: x=1
else: x=2'
10000 loops, best of 3: 40.5 usec per loop

$ python2.4 -mtimeit -s'import sys' 'if sys.version>="2.5": x=2
else: x=1'
1000000 loops, best of 3: 0.221 usec per loop
$ python2.6 -mtimeit -s'import sys' 'if sys.version>="2.5": x=2
else: x=1'
10000000 loops, best of 3: 0.156 usec per loop

Come si vede, la versione che considero più pulito è 10.8 / 0.221, quasi 50 volte più veloce, a 2,4, e 40.5 / 0.156, quasi 260 volte più veloce, il 2.6. In generale (con rare eccezioni), il pulito (cioè "divinatorio") approccio si rivelerà essere meglio ottimizzato quella in pitone - spesso, almeno una parte del motivo può essere che sviluppatori principali Python concentrarsi sulla agevolare e incoraggiare l'uso di costrutti che piace, piuttosto che quello di costrutti a loro non piace.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top