Python 2.5.2- wat was in plaats van 'met' verklaring

Ik schreef mijn code voor python 2.7 maar de server heeft 2.5. Hoe herschrijf ik de volgende code zodat deze in python 2.5.2 wordt uitgevoerd:

gzipHandler = gzip.open(gzipFile)

try:
    with open(txtFile, 'w') as out:
        for line in gzipHandler:
            out.write(line)
except: 
    pass

Op dit moment krijg ik de volgende foutmelding wanneer ik mijn script probeer uit te voeren:

Waarschuwing: 'with' wordt een gereserveerde sleutelwoord in Python 2.6 Traceback   (meest recente oproep laatste): bestand "Main.py", regel 7, in       van Extractor import Extractor File "/data/client/scripts/Extractor.py", regel 29       met open (self._logFile, 'w') als uit:               ^ SyntaxError: ongeldige syntaxis

Bedankt, Ron.

6

3 antwoord

In Python 2.5 kan je < de met -instructie gebruiken - het gewoon importeren vanuit __ toekomstig __ :

from __future__ import with_statement
19
toegevoegd
Woah, ik wist dat Python krachtig was, maar dat vermogen is gewoon indrukwekkend!
toegevoegd de auteur Mike Christensen, de bron
@retracile. Niet nodig - gewoon anti-zwaartekracht importeren :-)
toegevoegd de auteur ekhumoro, de bron
@syam: het kan ook worden voorafgegaan door de module docstring, opmerkingen, lege regels en andere toekomstige importen.
toegevoegd de auteur Sven Marnach, de bron
Ik wil van __future__ import flying_cars alstublieft.
toegevoegd de auteur retracile, de bron
from __future__ import with_statement moet de eerste regel van je python-bestand zijn (deze kan na de bang-regel worden geplaatst).
toegevoegd de auteur syam, de bron
ik wil van _future_ import hot_chicks pleaseee ... !!
toegevoegd de auteur diffracteD, de bron

Als u niet met kunt of wilt gebruiken, gebruik dan finally :

gzipHandler = gzip.open(gzipFile)
out = open(txtFile, 'w')
try:
    for line in gzipHandler:
        out.write(line)
finally:
    out.close()
    gzipHandler.close()

De opschooncode in de finally -clausule wordt altijd uitgevoerd, ongeacht of een uitzondering wordt verhoogd of niet.

3
toegevoegd
@KirkStrauser. Bedankt. Hopelijk nu gerepareerd.
toegevoegd de auteur ekhumoro, de bron
De laatste regel moet out.close() zijn.
toegevoegd de auteur Kirk Strauser, de bron

De "oude" versie van de code in uw try/except-blok zou zijn:

out = open(txtFile, 'w')
for line in gzipHandler:
    out.write(line)
out.close()

De met open() ... contextmanager is hier feitelijk hetzelfde. Python sluit bestanden automatisch wanneer hun objecten vuilnis zijn verzameld (zie vraag 575278 voor details), dus out wordt gesloten als de functie waarin het zich bevindt, niet meer wordt uitgevoerd. Bovendien zal het besturingssysteem het bestand sluiten wanneer het Python-proces wordt beëindigd als het om een ​​of andere reden catastrofaal mislukt voordat out.close() wordt uitgevoerd.

De met open() contextmanager wordt uitgebreid tot ongeveer:

out = open(txtFile, 'w')
try:
    for line in gzipHandler:
        out.write(line)
finally:
    out.close()

Zie de bovenstaande link naar "contextmanager" voor een uitleg. Dus hoe werkt het? Het opent het bestand, voert het codeblok uit en sluit vervolgens expliciet het bestand. Hoe werkt de "oude" versie die ik beschrijf,? Het opent het bestand, voert het codeblok uit en sluit vervolgens impliciet het bestand wanneer het bereik is voltooid of wanneer het Python-proces wordt beëindigd.

Opslaan, maar voor de 'expliciete' versus 'impliciete' onderdelen is de functionaliteit identiek.

1
toegevoegd
Deze code is heel anders dan wat een contextbeheerder doet. Deze code eet eenvoudig alle uitzonderingen die optreden tijdens de hele bewerking, zonder enige diagnose te geven (kanttekening: u wilt nooit een blote behalve -clausule in productiecode!). Een contextmanager zorgt ervoor dat de opschooncode wordt uitgevoerd, zelfs als er een uitzondering is opgetreden, maar de uitzondering doorgeeft. Dit kan worden gesimuleerd door een try/finally-verklaring.
toegevoegd de auteur Sven Marnach, de bron
In dit geval is het verschil hetzelfde als in het algemene geval. Uw code garandeert niet dat de opschoningscode wordt uitgevoerd (dat wil zeggen dat uw code niet garandeert dat het bestand wordt gesloten).
toegevoegd de auteur Sven Marnach, de bron
OK, het is nu veel duidelijker. Ik heb mijn downvote teruggenomen, hoewel sommige details nog steeds fout zijn. Een voorbeeld van een verkeerd detail is " out wordt gesloten wanneer de functie waarin het zich bevindt, om welke reden dan ook niet meer wordt uitgevoerd." Als de functie wordt uitgevoerd als gevolg van een uitzondering, bevat de uitzondering een traceback met een koppeling naar het frame, waardoor garbagecollection van het bestandsobject wordt voorkomen. Bovendien, in implementaties van Python anders dan CPython, kun je niet eens zeker zijn dat het bestand vuilnis verzameld is wanneer de functie terugkeert.
toegevoegd de auteur Sven Marnach, de bron
Het is totaal verschillend van wat een contextbeheerder doet in het algemeen. Maar kunt u een voorbeeld geven van hoe het wezenlijk verschilt van wat dit contextbeheer doet in dit specifieke geval? Wat zou het verschil in gedrag zijn?
toegevoegd de auteur Kirk Strauser, de bron
@SvenMarnach Ik heb mijn antwoord uitgebreid om het te verduidelijken. Het gedeelte behalve dat u in uw eerste opmerking noemt, was ook het OP, niet het mijne. Ik ben het ermee eens dat een blote behalve een slecht idee is en ik gebruik ze (bijna) nooit, maar voor demonstratiedoeleinden wilde ik zijn code niet te veel wijzigen.
toegevoegd de auteur Kirk Strauser, de bron