Python 2 oder 3 oder beides?

Alles, was nicht direkt mit Python-Problemen zu tun hat. Dies ist auch der perfekte Platz für Jobangebote.
mutetella
User
Beiträge: 1695
Registriert: Donnerstag 5. März 2009, 17:10
Kontaktdaten:

Hallo,

als ich vor fast 5 Jahren mit meinem Kalender begonnen habe (ich schmeiß' mich weg... :mrgreen: ), war Python 3 noch nicht wirklich Thema (ich begann damals mit 2.6). Als nächstes muss ich allerdings die eine und andere Encoding-Sünde bereinigen und stehe auch deshalb vor der Frage, ob ich mein Programm weiterhin (nur Python 2) oder (Python 2 und 3) oder (nur Python 3) lauffähig gestalten sollte.

Über was soll ich nachdenken? Was würdet ihr tun?

mutetella
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit ;-) )
BlackJack

@mutetella: Ich würde vorerst bei Python 2 bleiben. Hilft Dir so eine total subjektive Aussage jetzt echt weiter? :-)
Benutzeravatar
sparrow
User
Beiträge: 4193
Registriert: Freitag 17. April 2009, 10:28

Bei Sachen die ich neu mache sieht das im Moment so aus:

- Nach Möglichkeit unter beidem lauffähig. Das geht mit 2.7 und __future__ ganz gut.
- Sollte es doch Schwierigkeiten geben (Abhängige Bibliotheken, etc.) 2.7.

Im Gegensatz zu BlackJack muss ich nicht noch anderer Versionen der 2.x unterstützen.
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Na wenn du es kannst und keine aeusseren Einschraenkungen durch Abhaengigkeiten hast, solltest du beides unterstuetzen.

In dem speziellen Fall wuerde ich auch noch Python 4 auf dem Radar haben :twisted:
mutetella
User
Beiträge: 1695
Registriert: Donnerstag 5. März 2009, 17:10
Kontaktdaten:

BlackJack hat geschrieben:Ich würde vorerst bei Python 2 bleiben. Hilft Dir so eine total subjektive Aussage jetzt echt weiter?
Eine Antwort darauf, welchen Vorteil eine Migration auf Python 3 brächte, ist es ja irgendwie schon... :D
sparrow hat geschrieben:Nach Möglichkeit unter beidem lauffähig. Das geht mit 2.7 und __future__ ganz gut.
Gerade bei unicode literals ist das eine Vereinfachung, doch ohne weitere Weichen (z. B. range/xrange) geht's nicht. Das ist eben auch die Frage, ob ich mir das antun möchte... :)

mutetella
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit ;-) )
BlackJack

@mutetella: Bezüglich der Weichen gibt es ja das `six`-Modul.
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Außerdem sollte man IMHO auch überlegen, ob man krampfhaft eine `xrange()`-Kompatibilität schaffen muss oder ob man grundsätzlich `range()` verwendet. Oftmals fällt der Unterschied ja gar nicht ins Gewicht und somit läuft das Programm unter Python 2 dann vielleicht einen Wimpernschlag schneller auf Kosten von eher unschönem Kompatibilitätscode. Es kommt hier stark auf den Kontext an, ob man das wirklich braucht.
BlackJack

@snafu: Ein bedingtes ``range = xrange`` oder ``from six.moves import xrange`` ist nicht sooo hässlich, finde ich.

Edit: Etwas unschöner ist dann vielleicht dass man wenn man tatsächlich Python 2 `range()` meint ``list(range(…))`` schreiben muss, was sehr wahrscheinlich in Python 2 ein klein wenig ineffizienter ist. In CPython könnte man das kopieren der Liste wegoptimieren, ich weiss aber nicht ob das tatsächlich gemacht wird. Und es wäre Implementierungsabhängig. Also müsste man eigentlich ``list(xrange(…))`` schreiben und `range()` vergessen.
mutetella
User
Beiträge: 1695
Registriert: Donnerstag 5. März 2009, 17:10
Kontaktdaten:

Nachdem ich mich ja jetzt so ein wenig mit den Unterschieden Python 2 / 3 auseinandergesetzt habe, tu' ich mir schwer, eine klare Linie zwischen Python 2 und 3 zu finden...:
  • Was könnte wohl ein Grund dafür gewesen sein, ab Python 2.6 und 2.7 damit zu beginnen, teilweise Aufwärtskompatibilität zu schaffen? Weshalb nicht ein oder zwei 3.x Versionen abwärtskompatibel mit "deprecated" Sachen oder gleich ein harter Bruch?
  • Kommt es nur mir so vor oder ist seit Python 3 alles ein bischen hirrli-wirrli? Ich meine so Dinge wie
    • `callable` verschwindet ab 3.0, wird ab 3.2 wieder eingeführt
    • `configparser` wird ab 3.0 zu `ConfigParser`, `datetime` aber nicht zu `DateTime`
    • im Zuge von "all text is Unicode" ab 3.0 verschwindet auch das u'' literal, wird aber mit 3.3 wieder eingeführt
@BlackJack: Sind das so Dinge, weswegen man bei Dir immer wieder heraushört, dass Du mit Python 3 (noch) nicht so wirklich warm wirst?

Ich denke mal, ich werde vorerst auf 2.7 Basis weiter wursteln. Bis ich es denn je zu einem halbwegs nutzbaren Kalender schaffe, ist vielleicht auch Python 3 verlässlicher geworden.

mutetella
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit ;-) )
BlackJack

@mutetella: Auf Abwärtskompatibilität wurde immer viel Wert gelegt. Was bestimmte Änderungen die eigentlich schon länger gewollt waren, verhindert hat. Darum die Entscheidung bei Python 3 einen Bruch zu machen.

Bei `ConfigParser` hast Du jetzt etwas durcheinander gebracht. Das Modul hies in Python 2 noch so und in Python 3 nun `configparser`. Das wurde also dem `datetime` angeglichen.

Und bei `callable()` und dem ``u``-Prefix hatten sie sich halt gedacht das braucht keiner mehr, aber als dann nach mehreren Jahren immer noch nicht alle umgestiegen sind, machen solche Sachen es halt leichter Quelltext für *beide* Versionen zu schreiben. Das ``u`` haben viele Programmierer haben wollen. Man könnte also sogar sagen die sind ziemlich zäh in der Entwicklung, dass sie so etwas erst nach fast fünf Jahren einführen.

Ich werde mit Python 3 hauptsächlich deswegen nicht warm weil ich aus diversen Gründen noch an Python 2 gebunden bin. Und ich habe keine Lust zwei Versionen zu unterstützen und Code dafür zu pflegen. Nicht weil ich Python 3 jetzt per se als Nachteilig empfinde, sondern weil ich keinen gravierenden Vorteil sehe im Verhältnis zum Aufwand. Ich habe bei Python 2 alles was ich brauche und 3 lockt mit nichts was ich unbedingt haben will. Wenn es für mich etwas interessantes jenseits von CPython 2 gibt, dann ist das im Moment immer noch PyPy. :-)

Ansonsten nervt mich dieses „nun muss man sich keine Gedanken um Unicode mehr machen” was einem oft von Anfängern nachgeplappert wird wenn man sie nach den Vorteilen von Python 3 fragt. Was einfach mal nicht stimmt. Auch bei Python 3 muss man sich über Bytes und Zeichenketten Gedanken machen, sonst fällt man an den „Grenzen” auf die Schnauze. Nur der Default-Typ ist jetzt halt ein anderer. Und die Default-Kodierung halte ich für einen dummen Fehler. Einen der bei Java schon vor Jahrzehnten gemacht wurde. Da hätte man draus lernen können.
mutetella
User
Beiträge: 1695
Registriert: Donnerstag 5. März 2009, 17:10
Kontaktdaten:

BlackJack hat geschrieben:Und die Default-Kodierung halte ich für einen dummen Fehler.
Verstehe ich jetzt nicht. Python 3 kodiert doch nicht?

mutetella
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit ;-) )
BlackJack

@mutetella: Doch Python 3 geht an vielen Stellen wo Python 2 von ASCII ausgegangen ist, nun von der „Systemkodierung” aus. Wo man in Python 2 also mit Zeichen ausserhalb von ASCII auf die Nase gefallen ist und sich gefälligst Gedanken machen musste, funktioniert das in Python 3 einfach so. Der Haken: Es funktioniert nur solange man auf dem selben System mit der selben „Systemkodierung” ist. Wenn man also ordentlich Programmieren will, muss man nach wie vor überall an den „Grenzen” explizit eine Kodierung angeben. Nur werden insbesondere Anfänger auf diesen Umstand nicht mehr mit der Nase gestossen. Die finden das dann erst heraus wenn sie mit einem selbstgeschriebenen Programm einen Haufen Text in Dateien gespeichert haben, und das dann auf ein anderes System transferieren und dort dann feststellen dass das selbe Programm die eigenen Text-Dateien nicht mehr problemlos lesen kann, die es zuvor geschrieben hat. Das ist doch ganz grosse #&%!$…

An der Stelle hätte ich mir gewünscht, das als Default-Kodierung wenn man nichts angibt, systemunabhängig UTF-8 verwendet wird. Das kann alles kodieren was man in Unicode-Zeichenketten steckt, und man kann Programme und Daten problemlos zwischen Systemen austauschen.
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

BlackJack hat geschrieben:@snafu: Ein bedingtes ``range = xrange`` oder ``from six.moves import xrange`` ist nicht sooo hässlich, finde ich.
Ersteres muss noch mit ``try ... except`` geschmückt werden, was die Sache nicht mehr so schön macht. Letzteres zwingt zu einer zusätzlichen Abhängigkeit.

Wenn man mit einer der beiden Sachen kein Problem hat, dann ist ja alles toll. Ich habe mir jedenfalls ``range()`` in Code für beide "Welten" angewöhnt. Ein Fall, bei der die Performance eines ``range``-Iterators zum Tragen kam, ist bei mir noch nicht vorgekommen.
BlackJack

@snafu: Deswegen schrob ich ja ein bedingtes ``range = xrange``. Das würde ich aber sowieso in ein eigenes Modul auslagern um es nicht in jedem Modul schreiben zu müssen. Also dann entweder ``from my_porting_utils import *`` oder ``from six.moves.builtins import *`` am Anfang vom Modul. Und da handele ich mir lieber eine zusätzliche Abhängigkeit ein, in der mir schon jemand die Arbeit abgenommen hat, als `six` noch mal selber neu zu erfinden. Das ist ein kleines Paket und soweit ich das sehe reines Python. Also keine Abhängigkeit vor der man Angst haben muss. :-)

Performance ist bei `range()` in erster Linie auch Speicherberbrauch. Wenn man immer nur kleine Zahlen hat mag das gehen, aber wenn es in die tausende geht oder gar sechstellig wird, dann habe ich zumindest ein ungutes Gefühl. Und da mein Zeug nicht nur auf Desktop-Rechnern oder Servern läuft, sondern auch mal auf NAS oder Routern mit wenig Speicher und relativ schwachen Prozessoren, könnte es dort sogar problematisch werden.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

BlackJack hat geschrieben:Also dann entweder ``from my_porting_utils import *`` oder ``from six.moves.builtins import *`` am Anfang vom Modul. Und da handele ich mir lieber eine zusätzliche Abhängigkeit ein, in der mir schon jemand die Arbeit abgenommen hat, als `six` noch mal selber neu zu erfinden. Das ist ein kleines Paket und soweit ich das sehe reines Python. Also keine Abhängigkeit vor der man Angst haben muss. :-)
Ja, finde das auch besser, das Aliasing an ``six`` auszulagern als das Rad ggf. nochmal in schlechter zu erfinden.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

BlackJack hat geschrieben:@mutetella: Doch Python 3 geht an vielen Stellen wo Python 2 von ASCII ausgegangen ist, nun von der „Systemkodierung” aus. Wo man in Python 2 also mit Zeichen ausserhalb von ASCII auf die Nase gefallen ist und sich gefälligst Gedanken machen musste, funktioniert das in Python 3 einfach so. Der Haken: Es funktioniert nur solange man auf dem selben System mit der selben „Systemkodierung” ist. Wenn man also ordentlich Programmieren will, muss man nach wie vor überall an den „Grenzen” explizit eine Kodierung angeben. Nur werden insbesondere Anfänger auf diesen Umstand nicht mehr mit der Nase gestossen. Die finden das dann erst heraus wenn sie mit einem selbstgeschriebenen Programm einen Haufen Text in Dateien gespeichert haben, und das dann auf ein anderes System transferieren und dort dann feststellen dass das selbe Programm die eigenen Text-Dateien nicht mehr problemlos lesen kann, die es zuvor geschrieben hat. Das ist doch ganz grosse #&%!$…

An der Stelle hätte ich mir gewünscht, das als Default-Kodierung wenn man nichts angibt, systemunabhängig UTF-8 verwendet wird. Das kann alles kodieren was man in Unicode-Zeichenketten steckt, und man kann Programme und Daten problemlos zwischen Systemen austauschen.
Ob nun ASCII oder per default UFT-8: Der Anfänger bekommt Probleme dann doch nur mit, wenn es halt nicht klappt und das ist nur der Fall, wenn er bei ASCII nicht Englischen Texte nutzt oder bei UTF-8 eigentlich nie?

Warum wurde hier eigentlich nicht Explicit is better than implicit. befolgt? Also immer explizit das Encoding angeben, an den Schnittstellen nach draußen. Wenn nicht, dann Traceback.

Die Systemkodierung zu nehmen war irgendwie ziemlich dämlich. Da wäre UTF-8 wirklich die bessere Wahl gewesen.


Und ja, PyPy finde ich auch interessanter als Python 3... Wobei, wenn PyPy zu 3 kompatibel ist, hätte man zwei Fliegen mit...

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Richtig ätzend ist ja auch, dass ich bei ``print`` keine Codierung angeben kann :evil: Wieso sollte man auf Stdout (über ``print``) immer die Systemkodierung nutzen wollen?
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Hyperion hat geschrieben:Richtig ätzend ist ja auch, dass ich bei ``print`` keine Codierung angeben kann :evil:
Vorteil ist ja dass du in Python 3 auch deine eigene ``print``-Funktion schreiben kannst und sie dann ``print`` heißt. Wobei das wohl mit future-Import in Python 2.7 auch geht.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Leonidas hat geschrieben: Vorteil ist ja dass du in Python 3 auch deine eigene ``print``-Funktion schreiben kannst und sie dann ``print`` heißt. Wobei das wohl mit future-Import in Python 2.7 auch geht.
Sicher, aber dann müsste man sich ja erst "Mühe" machen. Von etwas so wichtigen wie ``print`` erwarte ich einfach, dass es gut funktioniert.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
BlackJack

@Hyperion: Man könnte auch `sys.stdout` entsprechend ersetzen.
Antworten