Wie gehen Sie mit fehlgeschlagenen zukünftigen Feature-Importen um? Wenn ein Benutzer mit Python 2.5 ausgeführt wird und die erste Anweisung in meinem Modul lautet:
from __future__ import print_function
Das Kompilieren dieses Moduls für Python 2.5 schlägt fehl mit:
File "__init__.py", line 1
from __future__ import print_function
SyntaxError: future feature print_function is not defined
Ich möchte den Benutzer darüber informieren, dass er das Programm mit Python> = 2.6 erneut ausführen muss, und möglicherweise einige Anweisungen dazu geben. Um jedoch PEP 236 zu zitieren :
Die einzigen Zeilen, die vor einer future_statement erscheinen können, sind:
- Das Modul docstring (falls vorhanden).
- Bemerkungen.
- Leerzeilen.
- Andere future_statements.
Also kann ich so etwas nicht machen:
import __future__
if hasattr(__future__, 'print_function'):
from __future__ import print_function
else:
raise ImportError('Python >= 2.6 is required')
Weil es ergibt:
File "__init__.py", line 4
from __future__ import print_function
SyntaxError: from __future__ imports must occur at the beginning of the file
Dieser Ausschnitt aus dem PEP scheint Hoffnung zu geben, es inline zu tun:
F: Ich möchte future_statements in try / exception-Blöcke einschließen, damit ich je nach der von mir ausgeführten Python-Version unterschiedlichen Code verwenden kann. Warum kann ich nicht?
Tut mir leid! try / Except ist eine Laufzeitfunktion. future_statements sind in erster Linie Gimmicks zur Kompilierungszeit, und Ihr Versuch / Ihre Ausnahme erfolgt lange nach Abschluss des Compilers. Das heißt, zu dem Zeitpunkt, an dem Sie versuchen / ausnehmen, ist die für das Modul geltende Semantik bereits abgeschlossen. Da der Versuch / außer nicht das erreichen würde, wie es aussehen sollte, ist es einfach nicht erlaubt. Wir möchten auch, dass diese besonderen Aussagen sehr leicht zu finden und zu erkennen sind.
Beachten Sie, dass Sie können direkt importieren __future__, und verwenden Sie die Informationen in sie, zusammen mit sys.version_info, um herauszufinden , wo die Freisetzung Sie unter steht in Bezug auf eine bestimmte Funktion Status ausführen.
Ideen?
quelle
#ifdef
Gimmick zur Kompilierungszeit ein, damit ich all diese__future__
Dinge in einem einzigen anmutig behandeln kann Datei? AAAARRGGGHHH .....if
zur Laufzeit verwenden. Auch fürimport
.Antworten:
"Ich möchte den Benutzer darüber informieren, dass er das Programm mit Python> = 2.6 erneut ausführen muss, und möglicherweise einige Anweisungen dazu geben."
Ist das nicht das, wofür eine README-Datei ist?
Hier ist deine Alternative. Ein "Wrapper": Ein kleiner Python-Blob, der die Umgebung überprüft, bevor Sie Ihr Ziel aop ausführen.
Datei: appwrapper.py
import sys major, minor, micro, releaselevel, serial = sys.version_info if (major,minor) <= (2,5): # provide advice on getting version 2.6 or higher. sys.exit(2) import app app.main()
Was "direkter Import" bedeutet. Sie können den Inhalt von überprüfen
__future__
. Sie sind immer noch an die Tatsache gebunden, dass afrom __future__ import print_function
Informationen für den Compiler sind, aber Sie können herumstöbern, bevor Sie das Modul importieren, das die eigentliche Arbeit erledigt.import __future__, sys if hasattr(__future__, 'print_function'): # Could also check sys.version_info >= __future__. print_function.optional import app app.main() else: print "instructions for upgrading"
quelle
'print_function' in __future__
das eigentlich nicht funktioniert ... sollte seinhasattr(__future__, 'print_function')
Eine ziemlich hackige, aber einfache Methode, die ich zuvor verwendet habe, besteht darin, die Tatsache auszunutzen, dass Byte-Literale in Python 2.6 eingeführt wurden, und am Anfang der Datei so etwas zu verwenden:
b'This module needs Python 2.6 or later. Please do xxx.'
Dies ist in Python 2.6 oder höher harmlos, in
SyntaxError
früheren Versionen jedoch harmlos . Jeder, der versucht, Ihre Datei zu kompilieren, erhält weiterhin eine Fehlermeldung, aber er erhält auch die Nachricht, die Sie geben möchten.Sie könnten denken, dass, da Sie diese Zeile nach Ihrem
from __future__ import print_function
haben müssen, es der Import ist, der die generiert,SyntaxError
und Sie die nützliche Fehlermeldung nicht sehen werden, aber seltsamerweise hat der spätere Fehler Vorrang. Ich vermute, dass der Fehler beim Import nicht wirklich ein Syntaxfehler an sich ist, sondern nicht beim ersten Kompilierungsdurchlauf ausgelöst wird und daher zuerst echte Syntaxfehler auftreten (aber ich vermute).Dies erfüllt möglicherweise nicht die Kriterien für "anmutig" und ist sehr Python 2.6-spezifisch, aber schnell und einfach durchzuführen.
quelle
b'This script requires Python 2.6, this line is a SyntaxError in earlier versions'
ist eine ziemlich klare Nachricht an den Benutzer, der eine Ausnahmespur liest, und an den Programmierer, der die Quelle liest.Setzen Sie einfach einen Kommentar in die gleiche Zeile
"from __future__ import ..."
wie folgt :from __future__ import print_function, division # We require Python 2.6 or later
Da Python die Zeile mit dem Fehler anzeigt, wird beim Versuch, das Modul mit Python 2.5 auszuführen, ein netter, beschreibender Fehler angezeigt:
from __future__ import print_function, division # We require Python 2.6 or later SyntaxError: future feature print_function is not defined
quelle