[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: 5537
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Mittwoch 7. Januar 2009, 16:58

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.
shcol (Repo | Doc | PyPi)
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Mittwoch 7. Januar 2009, 17:11

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:

Mittwoch 7. Januar 2009, 17:11

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: 5537
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Mittwoch 7. Januar 2009, 17:18

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...
shcol (Repo | Doc | PyPi)
BlackJack

Mittwoch 7. Januar 2009, 17:24

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: 5537
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Mittwoch 7. Januar 2009, 17:47

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."
shcol (Repo | Doc | PyPi)
Benutzeravatar
cofi
Moderator
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Mittwoch 7. Januar 2009, 19:25

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

Mittwoch 7. Januar 2009, 19:39

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: 5537
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Mittwoch 7. Januar 2009, 19:43

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.
shcol (Repo | Doc | PyPi)
Birne94
User
Beiträge: 90
Registriert: Freitag 28. November 2008, 15:18
Kontaktdaten:

Mittwoch 7. Januar 2009, 19:45

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

Mittwoch 7. Januar 2009, 19:46

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: 5537
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Mittwoch 7. Januar 2009, 19:48

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
shcol (Repo | Doc | PyPi)
lunar

Mittwoch 7. Januar 2009, 20:03

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
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Mittwoch 7. Januar 2009, 20:03

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 Modvoice
Benutzeravatar
snafu
User
Beiträge: 5537
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Mittwoch 7. Januar 2009, 20:36

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...
shcol (Repo | Doc | PyPi)
Antworten