Seite 1 von 2
Typ einer Variablen bestimmen
Verfasst: Donnerstag 5. April 2012, 09:29
von api
Hallo zusammen,
ich habe zum Beispiel die folgende Liste mit Variablen-Inhalten:
a_list = ['auto', '17', '['eine liste', 2]', '{TEST: 40, HAUS: 50}']
Nun möchte ich herausfinden, dass
- "a_list[0]" vom Typ String
"a_list[1]" vom Typ Integer
"a_list[2]" vom Typ List
"a_list[3]" vom Typ Dict
ist. Wie stelle ich das an? Mit "type" bekomme ich ja immer nur raus, dass es ein String ist - aber was ist mit dem Inhalt des Strings?
Ich hab da im Augenblick keinen Ansatz für - glaube aber, dass es so schwierig doch nicht sein kann?
Re: Typ einer Variablen bestimmen
Verfasst: Donnerstag 5. April 2012, 09:45
von cofi
Der Inhalt eines Strings sind Strings und das ist auch ihr Typ. Wenn sie Literale enthalten, sind das keine Literale, denn es sind ja Strings.
Wenn du denn String aber auswertest, zb mit `ast.literal_eval` kannst du den Typ _davon_ bestimmen.
Re: Typ einer Variablen bestimmen
Verfasst: Donnerstag 5. April 2012, 10:08
von api
Das ist genau das, was ich haben wollte
Was ich noch nicht ganz verstehe, warum ich bei:
eine Fehlermeldung erhalte?
Code: Alles auswählen
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python2.6/ast.py", line 68, in literal_eval
return _convert(node_or_string)
File "/usr/lib/python2.6/ast.py", line 67, in _convert
raise ValueError('malformed string')
ValueError: malformed string
Re: Typ einer Variablen bestimmen
Verfasst: Donnerstag 5. April 2012, 10:20
von EyDu
Weil du wahrscheinlich
meinst

Re: Typ einer Variablen bestimmen
Verfasst: Donnerstag 5. April 2012, 10:27
von api
@EyDu: Ok. Aber wie bekomme ich das mit meiner Liste hin, da steht als "a_list[0]" ja nur 'auto' drin - und nicht '"auto"'

Re: Typ einer Variablen bestimmen
Verfasst: Donnerstag 5. April 2012, 10:34
von /me
api hat geschrieben:@EyDu: Ok. Aber wie bekomme ich das mit meiner Liste hin, da steht als "a_list[0]" ja nur 'auto' drin - und nicht '"auto"'

Code: Alles auswählen
>>> print(a_list[0])
auto
>>> print(repr(a_list[0]))
'auto'
Re: Typ einer Variablen bestimmen
Verfasst: Donnerstag 5. April 2012, 10:37
von EyDu
Code: Alles auswählen
>>> type(ast.literal_eval('["test", 42]')[0])
<type 'str'>
Ehrlich gesagt sehe ich dein Problem nicht. Vielleicht solltest du ein konkretes Beispiel mit einer Liste geben, welches nicht funktioniert.
Re: Typ einer Variablen bestimmen
Verfasst: Donnerstag 5. April 2012, 10:43
von api
@/me: Danke soweit. Das Problem ist nur - um mal wieder auf mein ursprüngliches Problem zurückzukommen -, dass ich zum Zeitpunkt des Umwandelns ja gar nicht weiss, dass es sich um einen String handelt. Das bekomme ich ja erst mit "ast.literal_eval()" heraus.
Somit funktioniert zwar..
aber
liefert halt auch 'str', obwohl es 'int' ist.
Re: Typ einer Variablen bestimmen
Verfasst: Donnerstag 5. April 2012, 10:50
von api
@EyDu: Bei deinem Beispiel bin ich mit dir einer Meinung - das geht.
Aber nehmen wir mal die Liste:
und fragen dann ab:
Code: Alles auswählen
type(ast.literal_eval(a_list[0]))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python2.6/ast.py", line 68, in literal_eval
return _convert(node_or_string)
File "/usr/lib/python2.6/ast.py", line 67, in _convert
raise ValueError('malformed string')
ValueError: malformed string
Wo ist denn da mein Fehler?
Re: Typ einer Variablen bestimmen
Verfasst: Donnerstag 5. April 2012, 10:59
von cofi
Dein Fehler ist, dass du inhomogene Daten hast: Strings, die andere Daten enthalten, und Strings die fuer sich selbst stehen sollen. Das kann nicht funktionieren (oder bestenfalls nur mit Heuristiken).
Wie andere schon schon gesagt haben, damit ein String fuer ast.literal_eval wie ein String aussieht muss es ein String-Literal in dem String geben.
Du koenntest jetzt den ValueError abfangen und sagen, wenn das fehlschlug, muss das wohl ein richtiger String gewesen sein, allerdings kannst du dann keine Strings von fehlerhaften Literalen unterscheiden.
Und noch ein Problem: Was ist mit einem String-Literal wie '12', soll das immer eine Zahl werden oder auch nicht immer?
Die beste Loesung™ ist es homogene Daten zu nutzen, d.h. alles ist ein String und echte String-Literale sehen so aus: '"string"'.
Re: Typ einer Variablen bestimmen
Verfasst: Donnerstag 5. April 2012, 11:02
von EyDu
Na einfach mit
a_list liegt doch bereits als Python-Objekt vor. Wenn das noch immer nicht die Lösung sein sollte, dann weise ich dich noch einmal darauf hin, dein Problem genauer zu beschreiben und ein zusammenhängendes Stück Code zu schreiben.
Re: Typ einer Variablen bestimmen
Verfasst: Donnerstag 5. April 2012, 11:40
von api
@EyDu: Ich kann leider keinen Code posten, da ich ja noch gar keinen habe.
Mein Problem ist, dass ich aus einer Schnittstelle eine Liste geliefert bekomme, die zB wie schon beschrieben, so aussehen könnte:
(wohl etwas mehr Felder, aber dieser Schnipsel reicht ja bereits für die Beschreibung des Problems)
Nun muss ich in Abhängigkeit des Typs des Inhaltes des Strings verschiedene Dinge tun. Also so in der Form...
wenn vom Typ 'String' dann tue ...
wenn vom Typ 'Int' dann tue ...
Wenn ich den Typ erstmal habe, ist der Rest kein Problem mehr... Mit dem 'ast.literal_eval' geht das ja auch schon ganz gut und reicht mir eigentlich auch - nur wenn es halt nen String ist (aus meiner Sicht), dann gibts nen Problem.
Somit bin ich nun zu folgender Lösung gekommen:
Code: Alles auswählen
import ast
a_dict = {}
a_list = ['auto', '17', '["eine liste", 42]', '{"TEST":40, "HAUS": 50}']
for item in a_list:
try:
a_dict[item] = type(ast.literal_eval(item))
except:
a_dict[item] = type(ast.literal_eval(repr(item)))
print a_dict
Und das kommt dann heraus:
Code: Alles auswählen
{'["eine liste", 42]': <type 'list'>, 'auto': <type 'str'>, '17': <type 'int'>, '{"TEST":40, "HAUS": 50}': <type 'dict'>}
Re: Typ einer Variablen bestimmen
Verfasst: Donnerstag 5. April 2012, 11:48
von Hyperion
Mal blöd nachgefragt: Es handelt sich dabei nicht um JSON?
Ansonsten kann man doch mit `isinstance` arbeiten...
Re: Typ einer Variablen bestimmen
Verfasst: Donnerstag 5. April 2012, 12:01
von api
@Hyperion: Jetzt, wo du es so sagst... ja, mein Problem könnte ich auch mit 'isinstance()' erledigen...
Aber mit JSON hat es nichts zu tun...
Re: Typ einer Variablen bestimmen
Verfasst: Donnerstag 5. April 2012, 12:08
von Hyperion
api hat geschrieben:
Aber mit JSON hat es nichts zu tun...
Seltsame Schnittstelle... die entspricht also keinem Standard? Darf man fragen, wo die herstammt? Oder ist das Format ggf. änderbar?
Re: Typ einer Variablen bestimmen
Verfasst: Donnerstag 5. April 2012, 12:23
von api
Mit Schnittstelle meine ich, dass hier 1 hausinternes Programm Datensätze übergibt, die nunmal in diesem eigenen Format aufgebaut sind. Änderbar ist das nicht, muss als gegeben hingenommen werden. Es richtet sich aber nach keinem Standard...
Re: Typ einer Variablen bestimmen
Verfasst: Donnerstag 5. April 2012, 12:24
von snafu
Vielleicht aber trotzdem JSON probieren. Die nicht-kompatiblen Strings lässt man halt so stehen, wie sie sind:
Code: Alles auswählen
import json
def strings_to_objects(strings):
for s in strings:
try:
result = json.loads(s)
except ValueError:
result = s
yield result
Zumindest für dein Beispiel klappt das ganz gut:
Code: Alles auswählen
In [43]: list(strings_to_objects(a_list))
Out[43]: ['auto', 17, [u'eine liste', 42], {u'HAUS': 50, u'TEST': 40}]
Leider bringt `json.loads()` keinen `error`-Paramter mit, wo man eine Standardbehandlung für ungültige Typen definieren könnte. Dann wäre das Ganze nämlich mit einer simplen List Comprehension implementierbar.
Re: Typ einer Variablen bestimmen
Verfasst: Donnerstag 5. April 2012, 12:26
von Hyperion
Hm... das ist natürlich doof und man kann da wenig machen

Man fragt sich nur, was den ursprünglichen Entwickler getrieben hat, so ein eigenes Format zu generieren...
Edit: Grad noch gesehen. snafus Idee ist vielleicht gar nicht so verkehrt!
Re: Typ einer Variablen bestimmen
Verfasst: Donnerstag 5. April 2012, 12:39
von snafu
Wobei schon interesant wäre zu wissen, ob das Format Python-artig (`None`, `True`, ...) oder JSON-artig (`null`, `true`) ist. Generell finde ich jetzt nicht, dass soviel gegen die Anwendung von besagtem `literal_eval()` spricht, sofern der Input Python-Code ist bzw falls die uneinheitlichen Typbezeichnungen garnicht vorkommen.
Einen wirklich schönen Weg kann man bei einem nicht-standardisierten Format eh nicht gehen...
Re: Typ einer Variablen bestimmen
Verfasst: Donnerstag 5. April 2012, 13:04
von api
@snafu: Also "Null" oder "None" kommen nicht vor, dafür könnte es aber "True" geben - was dann wieder die Lösung mit dem `literal_eval()` favorisiert.