return value from file

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.
Antworten
taake
User
Beiträge: 125
Registriert: Donnerstag 14. Oktober 2010, 08:49

Hallo,

ich hab ein komisches Problem mit einem return
und zwar würde ich gerne einfach den inhalt einer datei als returnwert netzungen, allerdings klappt das mal so gar nicht und ich weiß nicht wo das problem ist.

Code: Alles auswählen

def AVAILABLE_THEMA():
    try:
        line = tuple(open('data/tmp/thema', 'r'))
        return line.strip()
#        return [('None','None'), ('Fleece','Fleece'), ('Stoffpuppe','Stoffpuppe')]
    except:
        return [('None','None')]
In der Datei steht genau das was im auskommentierten return steht, der wenn man ihn einkommentiert auch funktioniert.
Hab schon versucht das auf div. arten und weißen passend hinzubiegen, aber leider alles ohne erfolg.
Hab mitlerweile keine Ideen mehr wie man es noch schaffen könnte das ganze einfach nur aus einer datei auszulesen und zurückzugeben.
Hintergrund die Daten stammen aus ner Datenbank und ich möchte nicht bei jedem aufruf ein datenbankzugriff und das ganze nach möglichen variablen durchsuchen sondern das einmal machen und dann nur noch aus der datei sourcen sozusagen.

Nebenfrage: muss ich die datei eigentlich noch schließen wenn ich sie auf diese weise öffne?
xeike
User
Beiträge: 83
Registriert: Donnerstag 28. Februar 2013, 09:58

Hi!

Was gibt denn

Code: Alles auswählen

line = tuple(open('data/tmp/thema', 'r'))
print(line)
zurück? Kann man darauf strip() anwenden?
Nebenfrage: muss ich die datei eigentlich noch schließen wenn ich sie auf diese weise öffne?
ja. :wink:



Xe
Sirius3
User
Beiträge: 17747
Registriert: Sonntag 21. Oktober 2012, 17:20

Hallo taake,
nimm mal dein nacktes »except« raus, dann merkst Du auch, dass line.strip einen AttributeError wirft.
Willst Du wirklich 'None' in Anführungszeichen zurückgeben.
Nimm als Datenformat etwas sinnvolles zum Zwischenspeichern, wie json.
taake
User
Beiträge: 125
Registriert: Donnerstag 14. Oktober 2010, 08:49

xeike hat geschrieben:Hi!

Was gibt denn

Code: Alles auswählen

line = tuple(open('data/tmp/thema', 'r'))
print(line)
zurück? Kann man darauf strip() anwenden?
Nein, kann man nicht tuple hat kein strip() :(

Code: Alles auswählen

AttributeError: 'tuple' object has no attribute 'strip'
Steh ich also wieder am Anfang...

@Sirius3: Ja, genau das möchte ich, da mir die application dann nicht um die ohren fliegt wenn die datei nicht da ist oder es irgendwelche anderen probleme mit ihr gibt.
Brauch das in diesem Format, da es für ein 'dynamisches' drop down menu.
None soll an erster Stelle stehen damit ich mich wenn nichts ausgewählt nicht darum kümmern muss.


Aber gut wenn ihr auch keine Möglichkeit kennt, dann muss ich wohl schauen ob ich mir nur für diesen zweck irgendwas dreckiges zusammenhacken was den zweck erfüllt, schade dachte es gibt da ne leichtere lösung für.
Sirius3
User
Beiträge: 17747
Registriert: Sonntag 21. Oktober 2012, 17:20

:twisted: :twisted: :twisted: :twisted: :twisted:
Nimm als Datenformat etwas sinnvolles zum Zwischenspeichern, wie json.
taake
User
Beiträge: 125
Registriert: Donnerstag 14. Oktober 2010, 08:49

Sirius3 hat geschrieben::twisted: :twisted: :twisted: :twisted: :twisted:
Nimm als Datenformat etwas sinnvolles zum Zwischenspeichern, wie json.
Danke ich mag dich auch :) (nicht böse gemeint)

hab ein wenig mit json rumgespielt, allerdings scheint es recht anspruchsvoll zu sein, so auf anhieb bin ich nur in ein error nach dem anderen gelaufen ...
Selbst die Beispiele die ich mir angeschaut habe sind meist mit
ValueError("No JSON object could be decoded")
geendet ...

Allerdings hab ich eine andere lösung gefunden ... keine hübsche aber es funktioniert.

Code: Alles auswählen

def AVAILABLE_THEMA():
    try:
        lines = open('data/tmp/thema', 'r').read()
        return eval(lines)
        lines.close()
    except:
        return CHOISE_FALLBACK
Auch wenn ich ehrlich gesagt nicht wirklich weiß wieso das mit eval() klappt, aber sollte an dieser Stelle wohl ungefährlich sein.
BlackJack

@taake: JSON ist kein Stück anspruchsvoll und was Du da jetzt mit `eval()` machst *ist* gefährlich. Lass besser die Finger vom Programmieren. :roll:

Edit: Und zum Thema „funktioniert”: Die Datei wird nicht wieder geschlossen und *so* kannst Du die Datei auch nicht schliessen wenn das ``return`` erst nach dem Versuch zu schliessen käme, denn Du hast schon wieder nicht verstanden was für Werte an Deine Namen gebunden sind und würdest versuchen `close()` auf einer Zeichenkette aufzurufen, was unsinnig ist.
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

taake hat geschrieben:Auch wenn ich ehrlich gesagt nicht wirklich weiß wieso das mit eval() klappt
So funktioniert Programmieren nicht, man rät nicht so lange rum, bis man eine scheinbar funktionierende Lösung gefunden hat. Wenn man etwas nicht versteht, dann ist dort garantiert noch irgendwo ein Fehler eingebaut.
taake hat geschrieben:aber sollte an dieser Stelle wohl ungefährlich sein.
Ein eval auf Daten, welche aus einer Datei stammen, ist wohl so mit das gefährlichste was man mit eval anstellen kann. Da kann doch nun wirklich alles drin stehen!

Auch dein gezeigter Code ist grauenhaft. Der Funktionsname sagt nichts über die Funktion aus und hält sich kein Stück an PEP 8. Vielleicht als grobe Richtlinie: wenn in einem Funktionsnamen kein Verb vorkommt, dann ist der Name schlecht gewählt. Funktionen beschreiben (in der Regel) Tätigkeiten, das sollte der Name auch zeigen.

Dein try/except-Block ist eine ganz schlechte Idee. Damit werden alle Fehler abgefangen, welche in dem try-Block auftreten können. Du hast dort (nach deinem Verständnis des Codeablaufs) sogar einen Fehler eingebaut, welchen du so nie entdecken würdest. Bei einem except muss immer stehen welche Excpetions abgefangen werden sollen, sonst baut man sich schwer auffindbare Probleme ein.

Der oben angesprochene Fehler träte bei dem close auf, wenn der Code so ablaufen würde, wie du es vermutest. Allerdings wird der Code nie erreicht, da vorher das return ausgeführt wird. lines ist ein String (nicht einmal eine Liste, wie der Name impliziert!) und hat keine close-Methode. Würde die Zeile erreicht werden, dann würde der except-Block ausgeführt, obwohl die Daten in Ordnung sind. Nur durch Zufall funktioniert dein Code.

Natürlich wird dadurch die geöffnete Datei nie geschlossen, daher solltest du zum Öffenen das with-Statement verwenden. Dann kann man solche Dinge nicht mehr vergessen

Als letzter Punkt fällt noch auf, dass CHOISE_FALLBACK nicht viel mit Englisch zu tun hat. Hier wäre vielleicht auch eine Exception angebracht. Das hängt aber von der Funktion ab.

Zeig doch mal deinen json-Code. Damit lässt sich sicher eine vernünftige Lösung finden.
Das Leben ist wie ein Tennisball.
taake
User
Beiträge: 125
Registriert: Donnerstag 14. Oktober 2010, 08:49

BlackJack hat geschrieben:@taake: JSON ist kein Stück anspruchsvoll und was Du da jetzt mit `eval()` machst *ist* gefährlich. Lass besser die Finger vom Programmieren. :roll:

Edit: Und zum Thema „funktioniert”: Die Datei wird nicht wieder geschlossen und *so* kannst Du die Datei auch nicht schliessen wenn das ``return`` erst nach dem Versuch zu schliessen käme, denn Du hast schon wieder nicht verstanden was für Werte an Deine Namen gebunden sind und würdest versuchen `close()` auf einer Zeichenkette aufzurufen, was unsinnig ist.

Das ist das Problem, wenn man es sich nur durch selbststudien beibringt weil der "Informatik"-Lehrer nur Word und Excel in perfektion beherrschte, sonst aber nichts ... daher frage ich auch immer mal wieder hier und hoffe auf hilfe
und ja ich weiß das eval() scheisse ist, aber ich hätte damit sicher eine glänzende karriere bei orcale/adobe vor mir :lol:

Habs jetzt als zu überarbeiten kommentiert
xeike
User
Beiträge: 83
Registriert: Donnerstag 28. Februar 2013, 09:58

taake hat geschrieben:Allerdings hab ich eine andere lösung gefunden ... keine hübsche aber es funktioniert.
Wenn dir JSON zu kompliziert ist, dann pickel die Daten doch.

Siehe hier:
http://docs.python.org/3/library/pickle.html

Dateien kannst du mit "with" öffnen, dann werden sie auch wieder geschlossen.

Code: Alles auswählen

with open('data/tmp/thema', 'r') as thema_file:
    db_content = thema_file.read()
    # interpretiere db_content

return was_auch_immer

Daten, mit denen du in einer Funktion arbeitest, kannst du per Parameter übergeben. "Globale Parameter" wie "CHOISE_FALLBACK" erschweren die Lesbarkeit deines Quelltextes.

Also vielleicht so:

Code: Alles auswählen

def available_data_as_list(filename, return_default):
    # mach was auch immer deine Funktion tun soll
    pass
    return 23



Xe
Sirius3
User
Beiträge: 17747
Registriert: Sonntag 21. Oktober 2012, 17:20

@xeike: kannst Du mir nochmal erklären, was an pickle einfacher ist als an json? 8)

Code: Alles auswählen

import pickle
import json

data = [('None','None'), ('Fleece','Fleece'), ('Stoffpuppe','Stoffpuppe')]
with open('data.pkl','wb') as output:
    pickle.dump(data, output)

with open('data.pkl','rb') as input:
    data = pickle.load(input)

with open('data.json','w') as output:
    json.dump(data, output)

with open('data.json','r') as input:
    data = json.load(input)
taake
User
Beiträge: 125
Registriert: Donnerstag 14. Oktober 2010, 08:49

So hab das ganze nochmal überarbeitet, hab auch irgendwie das Gefühl das man einer hier zu viel in den source interpretiert, aber gut, viel hat man davon nicht gesehen.

Daher mal der ganze (überarbeitet) source

Code: Alles auswählen

from wtforms import Form, TextField, validators, SelectField, BooleanField
import ast

CHOICE_FALLBACK = [("None","None")]

def AVAILABLE_THEMA():
    try:
        with open('data/tmp/thema', 'r') as content_file:
            av_thema = content_file.read()
            return ast.literal_eval(av_thema)
    except:
        return CHOICE_FALLBACK

class SearchForm(Form):
    artnr = TextField('Artikel Nummer', [validators.optional(), validators.Length(min=4, max=8)
    [...]
    thema = SelectField('Thema', choices=AVAILABLE_THEMA())
Macht jetzt das was es soll, schließt die Datei automatisch (danke @xeike)
und der eval sollte auch sicher sein.
ast.literal_eval(node_or_string)

Safely evaluate an expression node or a string containing a Python expression. The string or node provided may only consist of the following Python literal structures: strings, bytes, numbers, tuples, lists, dicts, sets, booleans, and None.

This can be used for safely evaluating strings containing Python expressions from untrusted sources without the need to parse the values oneself.
Damit kann ich mir an dieser Stelle json bzw. pickle sparen @Sirius3 danke für die json / pickle beispiele, auch wenn sie nicht für mich waren habe ich nun zumindest eine Ahnung was vorhin beim rumspielen damit nicht so geklappt hat.
@EyDu: danke für den backround und das mit der exception ist so gewollt das die alles abfängt, sonst fiegt mir das ganze formular um die ohren und der code recht überschaubar ist finde ich es an der stelle vertretbar.
@BlackJack: Danke für deine aufbauenden Worte 8)
Sirius3
User
Beiträge: 17747
Registriert: Sonntag 21. Oktober 2012, 17:20

taake hat geschrieben:... und der code recht überschaubar ist finde ich es an der stelle vertretbar.
soll ich Dich jetzt für den größten Komiker hier im Forum oder einfach nur für ignorant halten?
Genau wegen dieses »except« hast Du dreimal hier nachfragen müssen und hast Deine eigenen Programmierfehler nicht erkannt.
Möchte nochmal aus Deinem ersten Post hier zitieren:
taake hat geschrieben:ich hab ein komisches Problem mit einem return
Genau solche „komischen“ Probleme treten auf, weil man sich selbst AttributeErrors oder NameErrors durch nackte »except«s verschleiert.
xeike
User
Beiträge: 83
Registriert: Donnerstag 28. Februar 2013, 09:58

Sirius3 hat geschrieben:@xeike: kannst Du mir nochmal erklären, was an pickle einfacher ist als an json? 8)
*lach*

:lol:

Nicht einfacher, nur anders. :wink:

Xe
webspider
User
Beiträge: 485
Registriert: Sonntag 19. Juni 2011, 13:41

Manchmal frage ich mich ob Leute, die den Unterschied zwischen Code und Daten nicht wahrhaben wollen besser Lisp erlernen sollten. Aber nur manchmal, denn es scheint einer Menge Programmierer zu hoch zu sein damit tatsächlich sinnvolles anzustellen.
taake
User
Beiträge: 125
Registriert: Donnerstag 14. Oktober 2010, 08:49

Sirius3 hat geschrieben: soll ich Dich jetzt für den größten Komiker hier im Forum oder einfach nur für ignorant halten?
Wer wäre ich, mich dort einzumischen - jeder soll sich selbst seine Meinung bilden.

Aber recht hast du natürlich.

Hab mein except jetzt erweitert.

Code: Alles auswählen

 except Exception, err:
        sys.stderr.write('ERROR: %s\n' % str(err))
Dachte nur immer ich müsste für jede eventualität einen eigenen execpt anlegen, aber scheinbar kann ich es auch global machen.
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

taake hat geschrieben:

Code: Alles auswählen

except Exception, err:
Solltest du ein halbwegs aktuelles Python (>= 2.6) verwenden, dann verwende die neue Syntax.

Code: Alles auswählen

except Exception as err:
BlackJack

@taake: Warum hast Du da überhaupt so ein allgemeines ``except:``? Entweder weiss man ganz konkret welche Ausnahme(n) man erwartet und wie man in einem ``except`` *sinnvoll* darauf reagieren kann, oder man lässt es einfach weg. *Dann* bekommt man bei unerwarteten Ausnahmen nicht nur die Ausnahme und die damit verbundene Nachricht, sondern auch noch einen Traceback, der einen genau auf die Zeile hinweist in der es das Problem gab, *und* die Aufrufreihenfolge die zu diesem Problem geführt hat. Also die Sachen, die man wissen möchte um einem Fehler auf den Grund zu gehen.

Der Vorteil von Ausnahmen gegenüber Fehlercodes die überall zurück gegeben werden, ist ja gerade, dass man nicht direkt bei jedem Aufruf auf einen Fehler reagieren muss, das andererseits aber auch kein Fehler unbemerkt ignoriert wird, weil man vergessen hat zu prüfen.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

webspider hat geschrieben:Manchmal frage ich mich ob Leute, die den Unterschied zwischen Code und Daten nicht wahrhaben wollen besser Lisp erlernen sollten. Aber nur manchmal, denn es scheint einer Menge Programmierer zu hoch zu sein damit tatsächlich sinnvolles anzustellen.
Auch Lisp-Programmierer ´´eval´´en nicht jedes dahergelaufene Stück Daten das nicht bei 3 aufm Baum war ;)
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:

Ein ``try... except`` ohne explizite Angabe der Exeption, die man erwartet, sollte man *nie* verwenden! Wenn Du keine Ahnung hast, was da an Exception kommt, lass das ´´try... except`` einfach weg.

Edit: Oops... hab gar nicht gesehen, dass es noch eine Seite gab, auf der das schon angesprochen worden ist :oops:
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Antworten