Unterstützung verschiedener Versionen von Python

8

Dieses Thema hat mich für einige Zeit gestört.

Für mein Python-Projekt wollte ich die Python-Versionen 2.4 bis 3.1 unterstützen können. Ich dachte ein wenig darüber nach, wie ich das machen könnte, und entschied mich schließlich, vier separate Forks des Quellcodes für vier verschiedene Versionen von Python zu haben: 2.4, 2.5, 2.6 und 3.1.

Ich bin zu der Ansicht gekommen, dass dies eine schlechte Entscheidung ist, hauptsächlich wegen Pythons Verteilungsverärgerung, die ich jetzt vier Mal statt einer machen muss.

Die Frage ist, was zu tun ist?

Mein Projekt befindet sich im Bereich der wissenschaftlichen Datenverarbeitung. Ich habe den Eindruck, dass es immer noch viele Leute gibt, die auf Python 2.4 angewiesen sind.

Jemand schlug vor, ich schreibe mein gesamtes Projekt für 2.4, aber das ist inakzeptabel für mich. Das bedeutet, dass ich keine Kontextmanager verwenden kann, und darauf werde ich nicht verzichten.

Wie unterstützen normale Python-Projekte 2.4? Vermeiden sie die Verwendung von Kontextmanagern?

Gibt es auch eine andere Variante als Python 3.1? Ich weiß, dass es alle Arten von Hacks gibt, um denselben Code auf 2.x und 3.x laufen zu lassen, aber einer der Gründe, warum ich Python mag, ist, dass der Code schön ist und ich es nicht tolerieren werde, ihn mit Kompatibilitäts-Hacks hässlich zu machen.

Bitte geben Sie mir Ihre Meinung.

    
Ram Rachum 09.12.2009, 14:11
quelle

6 Antworten

1

Ja, Sie müssen für die Python 2.4-Syntax schreiben, um alle 2.4 - 2.7 in der gleichen Codebasis zu unterstützen.

Einige Änderungen in Python 2.6 und 2.7 zielen darauf ab, es leichter zu machen, kompatiblen Code mit 3.x zu schreiben, aber Sie müssen die Unterstützung für 2.5 und darunter fallen lassen, um das zu tun.

    
Mauve 09.12.2009 14:32
quelle
1

Es scheint verschiedene Antworten auf Ihr Problem zu geben.

Erstens, wenn Sie alle Funktionen für alle Python-Versionen anbieten wollen, dann sind Sie wahrscheinlich mit der kleinstmöglichen Funktionalitäts-Untermenge beschäftigt - daher schreiben Sie Ihren Code für Python 2.4. Oder Sie können Funktionen neuere Interpreter rückportieren, wenn sie reine Pythons sind (das gilt nicht für Kontextmanager oder Coroutinen).

Oder Sie können die Versionsunterstützung in Features aufteilen. Wenn Sie glauben, dass es eine (optionale) Funktion gibt, die beispielsweise von Context Managern profitieren würde, können Sie sie in einem separaten Modul bereitstellen Habe diese Funktion nicht.

Um Python 3 zu unterstützen, werfen Sie einen Blick auf den 2to3-Helfer. Wenn Sie Ihren Code richtig schreiben, besteht eine gute Chance, dass Sie nicht zwei separate Codebasen pflegen müssen.

    
Alan Franzoni 09.12.2009 14:58
quelle
0

Wenn die Unterschiede zwischen den Versionen nicht extrem sind, können Sie versuchen, sie in ein separates Paket oder Modul zu isolieren, in dem Sie versionsspezifischen Code schreiben, der als Anpassungsschicht dient.

Auf einfache Weise kann dies in einfachen Fällen ohne das separate Modul geschehen, beispielsweise wenn eine neue Version von Python ein Paket erstellt, das früher extern war, wie zum Beispiel simplejson. Wir haben etwas ähnliches in einem Code:

%Vor%

Für nicht-triviale Dinge wie das, was Sie wahrscheinlich haben, würden Sie nicht wollen, dass solche Dinge zufällig in Ihrer Code-Basis verteilt werden, also sollten Sie alles zusammen an einem Ort sammeln, wenn möglich, und das zum einzigen Abschnitt machen Ihres Codes, der versionsspezifisch ist.

Dies kann nicht so gut für Dinge funktionieren, bei denen die Syntax anders ist, z. B. Ihr Kommentar über die Verwendung von Kontextmanagern. Sicher, Sie könnten den Context-Manager-Code in ein separates Modul einfügen, aber das wird wahrscheinlich die Orte komplizieren, an denen Sie es verwenden würden. In solchen Fällen können Sie bestimmte kritische Funktionen (ich denke, dass Kontext-Manager leicht simuliert werden können) zu diesem Adaptermodul zurückportieren.

Es ist definitiv das Schlimmste, was Sie tun könnten, wenn Sie separate Codebasen haben. Ich würde Ihnen daher empfehlen, davon wegzuarbeiten. Zumindest nicht willkürlich Features aus neueren Versionen von Python verwenden, da es zwar nett erscheinen mag, sie im Code zu haben (vielleicht einen bestimmten Logikblock zu vereinfachen), die Tatsache, dass Sie diese Logik duplizieren müssen, indem Sie die Codebase, sogar auf einem einzigen Modul, wird die Vorteile mehr als zunichte machen.

Wir bleiben bei älteren Versionen für Legacy-Code und optimieren, wenn neue Releases herauskommen, um sie zu unterstützen, aber die Unterstützung für die älteren beibehalten, manchmal mit kleinen Adapter-Layern. Irgendwann zeigt sich eine große Version unseres Codes im Zeitplan, und wir überlegen, ob es an der Zeit ist, die Unterstützung für ein älteres Python fallen zu lassen. Wenn das passiert, versuchen wir, mehrere Versionen zu überspringen, indem wir zum Beispiel direkt von 2.4 auf 2.6 gehen und erst dann anfangen, die neue Syntax und nicht anpassungsfähige Funktionen wirklich zu nutzen.

    
Peter Hansen 09.12.2009 14:54
quelle
0

Zunächst einmal müssen Sie daran denken, dass Python 2.x die gleiche Syntax teilt, die abwärtskompatibel ist, neue Funktionen & amp; Ergänzungen beiseite. Es gibt andere Dinge zu beachten, die nicht unbedingt Fehler sind, wie DeprecationWarning-Nachrichten, die zwar nicht schädlich sind, aber hässlich sind und Verwirrung stiften können.

Python 3.x ist von vornherein NICHT-INKOMPATIBEL und beabsichtigt, den alten Haufen zurückzulassen. Python 2.6 führte viele Änderungen ein, die auch in Python 3.x enthalten sind, um den Übergang zu erleichtern. Um alle zu sehen, würde ich empfehlen, das Neues in Python 2.6 Dokument zu lesen. Aus diesem Grund ist es sehr gut möglich, Code für Python 2.6 zu schreiben, der auch in Python 3.1 läuft, aber das ist nicht ohne Vorbehalte.

Sogar noch gibt es viele geringfügige Syntaxänderungen sogar zwischen Versionen 2.x, die erfordern, dass Sie einen großen Teil Ihres Codes in try / except blockieren, also wenn Sie das dann tun wollen ein 2.x und 3.x Zweig ist völlig möglich. Ich denke, Sie werden feststellen, dass Sie eine Menge von Attribut- und Typprüfungen an Ihren Objekten durchführen werden, um das zu tun, was Sie tun möchten.

Ich würde Ihnen empfehlen, sich den Code wichtiger Projekte anzusehen, die verschiedene Python-Versionen unterstützen. Twisted Matrix ist die erste, die einem in den Sinn kommt. Ihr Code ist ein wunderbares Beispiel dafür, wie Python-Code geschrieben werden sollte.

Am Ende wird es nicht einfach sein, was du vorhast, also bereite dich auf eine Menge Arbeit vor!

    
jathanism 09.12.2009 18:52
quelle
0

Sie können virtualenv ausprobieren und Ihre Anwendung mit einer einzigen Python-Version verteilen. Dies kann oder kann in Ihrem Fall jedoch nicht praktikabel sein.

    
zeemonkee 09.12.2009 19:28
quelle
0

Wir haben ein verwandtes Problem, ein großes System, das sowohl jython als auch cpython zurück auf 2.4 unterstützt. Im Grunde müssen Sie Code, der anders geschrieben werden muss, in eine hoffentlich kleine Menge von Modulen eingrenzen und die Dinge bedingt importieren lassen.

%Vor%

In Ihrem Beispiel würden Sie wahrscheinlich Tests gegen sys.version_info verwenden. Sie könnten einige einfache Dinge in einem Utility-Modul definieren, die Sie verwenden würden: from util import *

%Vor%

Dann Dinge in util_py4.py wie:

%Vor%

Obwohl dies ein anderes Problem ist als die Portierung (da Sie weiterhin unterstützen möchten), bietet dieser Link einige nützliche Anleitungen Ссылка (wie auch eine Vielzahl anderer Artikel über die Portierung von Python 2.x).

Ihr Kommentar, dass Sie ohne Kontextmanager nicht leben können, ist ein wenig verwirrend. Während Kontext-Manager leistungsfähig sind und den Code lesbarer machen und das Risiko von Fehlern minimieren, können Sie sie einfach nicht im Code Ihrer 2.4-Version finden.

%Vor%

Da Sie 2.4 unterstützen möchten, haben Sie einen Code, der nur die zweite Syntax haben muss. Wird es wirklich eleganter sein, beides zu schreiben?

    
Marvin 23.03.2012 15:48
quelle