[gelöst] Python-Version auslesen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Hallo!

Mein Programm soll etwas anderes tun, wenn die Python-Version kleiner als 2.6 ist. Gibt es einen besseren Weg als das?

Code: Alles auswählen

import sys
version = float(sys.version[:3])
if version < 2.6:
    print 'kleiner'
Zuletzt geändert von snafu am Donnerstag 8. Januar 2009, 22:17, insgesamt 3-mal geändert.
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

snafu hat geschrieben: Mein Programm soll etwas anderes tun, wenn die Python-Version kleiner als 2.6 ist. Gibt es einen besseren Weg als das?

Code: Alles auswählen

import sys
version = float(sys.version[:3])
if version < 2.6:
    print 'kleiner'
Ist doch in Ordnung so. Du kannst natürlich auch sys.version_info verwenden. Wenn du es ganz anders haben willst, hätte ich noch diese Lösung anzubieten: :lol:

Code: Alles auswählen

>>> try:
...     (1,).count(1)
... except AttributeError:
...     print "kleiner"
... 
kleiner
Redprince
User
Beiträge: 128
Registriert: Freitag 22. Oktober 2004, 09:22
Wohnort: Salzgitter
Kontaktdaten:

Den Inhalt von sys.version_info hast du dir angesehen?
I am not part of the allesburner. I am the [url=http://allesburner.de]allesburner[/url].
Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Jau, version_info finde ich persönlich sauberer.

Code: Alles auswählen

import sys
major, minor = sys.version_info[:2]
if major <= 2 and minor < 6:
    print 'kleiner'
Danke. :)

EDIT: Obwohl, nee. AND ist hier gar nicht gut...
BlackJack

Ich würde auf jeden Fall auch mal schauen, ob man das ohne die Versionsnummer machen kann. Hängt natürlich davon ab, was man machen möchte.

Edit: Wenn Du das ``and`` nicht magst:

Code: Alles auswählen

if sys.version_info[:2] < (2, 6):
    # ...
Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Das ist es. Danke BlackJack. :)

Es geht um mein "Modul-Lokalisierungs-Skript". Dort zeigt imp.find_module() unterschiedliche Verhaltensweisen, wenn man einen leeren String übergibt:

Code: Alles auswählen

Python 2.6 (r26:66714, Nov 16 2008, 20:39:17) 
[GCC 4.3.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import imp
>>> imp.find_module('')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named 
>>> 
Python 2.5.2 (r252:60911, Nov 14 2008, 19:46:32) 
[GCC 4.3.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import imp
>>> imp.find_module('')
(None, '/usr/lib/python2.5/site-packages/PIL/', ('', '', 5))
Der Einheitlichkeit halber möchte ich an dieser Stelle Python < 2.6 das selbe Verhalten (ImportError werfen) beibringen wie der aktuellen Version.

http://paste.pocoo.org/show/98461/ (bisherige Version ohne die Anpassung)

EDIT: Obwohl, eigentlich ist das Unsinn. Die Meldung "No module named" ist ja ohnehin eher verwirrend. Ich werfe jetzt unabhängig von der Python-Version einen ImportError: "Module string is empty."
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

snafu hat geschrieben:EDIT: Obwohl, eigentlich ist das Unsinn. Die Meldung "No module named" ist ja ohnehin eher verwirrend. Ich werfe jetzt unabhängig von der Python-Version einen ImportError: "Module string is empty."
Macht es nicht mehr Sinn zu kontrollieren ob der String leer ist? ;)
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

snafu hat geschrieben:EDIT: Obwohl, eigentlich ist das Unsinn. Die Meldung "No module named" ist ja ohnehin eher verwirrend. Ich werfe jetzt unabhängig von der Python-Version einen ImportError: "Module string is empty."
Wieso ist die Meldung verwirrend? Ist doch eine klare Aussage: "Es wurde kein Modul benannt." Das trifft doch exakt den Punkt.
Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

cofi hat geschrieben:Macht es nicht mehr Sinn zu kontrollieren ob der String leer ist? ;)
Mach ich ja auch jetzt:

Code: Alles auswählen

def get_path(module):
    "Return module's path. Return None if module is no file."
    if module == '':
        raise ImportError, 'Module string is empty.'
    f, path = imp.find_module(module)[:2]
    if f == None:
        return None
    try:
        return path
    finally:
        f.close()
@numerix: Die Meldung an sich ist nicht verwirrend. Sie sieht nur komisch aus, wenn dahinter kein Name steht, weil der übergebene String eben leer ist.
Birne94
User
Beiträge: 90
Registriert: Freitag 28. November 2008, 15:18
Kontaktdaten:

sry, wenn ich was hier nicht peile (ka. ob ich aufm schlauch stehe), aber wieso wird da das return mit try abgefangen?
Um den Stream nach dem beenden der Funktion zu schließen? Denn ein Fehler kann da nicht so wirklich bei rauskommen, oder?
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

snafu hat geschrieben:@numerix: Die Meldung an sich ist nicht verwirrend. Sie sieht nur komisch aus, wenn dahinter kein Name steht, weil der übergebene String eben leer ist.
Ah, verstehe: Die Meldung ist eigentlich gar nicht so gemeint wie ich das übersetzt habe, sondern eigentlich steht da "Es gibt kein Modul mit dem Namen <Argument>" und dann fehlt der Name, weil kein Argument übergeben wurde. :idea: Dann ist es wirklich nicht schön.
Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Birne94 hat geschrieben:wieso wird da das return mit try abgefangen?
Um den Stream nach dem beenden der Funktion zu schließen? Denn ein Fehler kann da nicht so wirklich bei rauskommen, oder?
Da offene Streams auf jeden Fall geschlossen werden sollten, wollte ich auch den sehr unwahrschenlich, aber theoretisch dennoch möglichen Fall einbeziehen, dass die print-Zeile eine Exception wirft. Schaden kann es IMHO jedenfalls nicht.

EDIT: Obwohl, du hast Recht. Ich hatte das vorher anders strukturiert und da hatte es für mich mehr Sinn gemacht. Wenn aus irgendeinem Grund nicht auf Listenindex 1 (also das was ich an "path" binde) zugegriffen werden kann, würde er ja schon vorher meckern. Ich mach's raus...

(Ich frage mich gerade ohnehin, ob ein "finally" eigentlich greift, wenn im try-Block ein "return" steht)

Code: Alles auswählen

def get_path(module):
    "Return module's path. Return None if module is no file."
    if module == '':
        raise ImportError, 'Module string is empty.'
    f, path = imp.find_module(module)[:2]
    if f == None:
        return None
    f.close()
    return path
lunar

So unwahrscheinlich ist das gar nicht. Einen "broken pipe"-Fehler kann man recht leicht provozieren. Folgendes Skript namens "broken_pipe.py":

Code: Alles auswählen

import time

for i in xrange(5000):
    time.sleep(0.01)
    print 'hello world'
Die Ausgabe dieses Skripts an "head" pipen:

Code: Alles auswählen

$ python broken_pipe.py | head -n5
hello world
hello world
hello world
hello world
hello world
Traceback (most recent call last):
  File "/home/lunar/test/broken_pipe.py", line 5, in <module>
    print 'hello world'
IOError: [Errno 32] Broken pipe
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Statt ``if f == None:`` besser ``if f is None`` denn ``None`` ist tatsächlich ein Singleton und man kann auf Objektidentität testen.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Leonidas hat geschrieben:Statt ``if f == None:`` besser ``if f is None`` denn ``None`` ist tatsächlich ein Singleton und man kann auf Objektidentität testen.
Okay, danke. War mir nicht bekannt.

@lunar: Selbst wenn ich jetzt mehrere Zeilen (z.B. für mehrere Module) ausgeben und diese Ausgabe tatsächlich durch ein Programm wie "head" begrenzen würde, dann wäre das Dateiobjekt aber in meinem Fall trotzdem geschlossen, bevor das print aus main() etwas in die Konsole schreibt, oder? Also jetzt bezogen auf die Variante ohne "finally".

Also kann ja eigentlich nur. Im Prinzip würde das nur Sinn machen, wenn ich das print-Statement direkt in die Funktion einbaue und ausführen lasse, bevor "f" geschlossen wird, was aber IMHO alles andere als guter Stil wäre...
lunar

snafu hat geschrieben:@lunar: Selbst wenn ich jetzt mehrere Zeilen (z.B. für mehrere Module) ausgeben und diese Ausgabe tatsächlich durch ein Programm wie "head" begrenzen würde, dann wäre das Dateiobjekt aber in meinem Fall trotzdem geschlossen, bevor das print aus main() etwas in die Konsole schreibt, oder? Also jetzt bezogen auf die Variante ohne "finally".
Vom "Datei-Objekt" kann man ja nicht mehr sprechen, da der Python-Interpreter zu diesem Zeitpunkt tot ist. Auf Betriebssystemebene werden die Ressourcen des Prozesses auf jeden Fall geschlossen, allerdings liegt zwischen dem Python-Interpreter und dem System noch die Standardbibliothek von C, die meist noch puffert. Dieser interne Puffer geht verloren, wenn sich das Programm nicht sauber beendet. Wenn man nur liest, ist das egal, weil der Puffer eh nur wiedergibt, was sich auf der Festplatte befindet.

Beim Schreiben allerdings gehen unter Umständen Daten verloren, deshalb sollte man Dateien, in die man schreibt, immer mit finally schließen oder innerhalb eines with-Statements verwenden. Nur so kann garantiert werden, dass die internen Puffer sauber gelehrt werden, sprich dass alle Daten, die man per "write" in die Datei schreibt, auch wirklich auf der Platte landen.
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Leonidas hat geschrieben:Statt ``if f == None:`` besser ``if f is None`` denn ``None`` ist tatsächlich ein Singleton und man kann auf Objektidentität testen.
In dem Sinne kannst du auch `if module == '':' anpassen -> `if not module:'
Benutzeravatar
str1442
User
Beiträge: 520
Registriert: Samstag 31. Mai 2008, 21:13

try: return ... except / finally: funktioniert immer.
BlackJack

@cofi: Das geht nicht, weil vom ersten Fall dann auch `None` erfasst würde, das im gezeigten Quelltext aber anders behandelt werden soll als die leere Zeichenkette.
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Wobei die Trennung von leeren Strings und None keinen großen Sinn ergibt bzw man bei None ebenfalls den ImportError (oder vielleicht besser einen ValueError?) raisen könnte.
Antworten