webentwicklung-frage-antwort-db.com.de

Die beste Möglichkeit, Variablenwerte aus einer Textdatei abzurufen - Python - Json

Bezüglich dieser Frage habe ich ein ähnliches - aber nicht dasselbe - Problem.

Auf meinem Weg werde ich eine Textdatei haben, die wie folgt strukturiert ist:

var_a: 'home'
var_b: 'car'
var_c: 15.5

Und ich brauche, dass der Python die Datei liest und dann eine Variable namens var_a mit dem Wert 'home' und so weiter erstellt.

Beispiel:

#python stuff over here
getVarFromFile(filename) #this is the function that im looking for
print var_b
#output: car, as string
print var_c
#output 15.5, as number.

Ist das möglich, ich meine sogar den var-Typ behalten?

Beachten Sie, dass ich die volle Freiheit für die Textdateistruktur habe. Ich kann das Format verwenden, das mir gefällt, wenn das von mir vorgeschlagene nicht das beste ist.

EDIT: Der ConfigParser kann eine Lösung sein, aber ich mag ihn nicht so sehr, denn in meinem Skript muss ich mich dann auf die Variablen in der Datei beziehen

config.get("set", "var_name")

Aber ich würde es lieben, auf die Variable direkt zu verweisen, wie ich sie im Python-Skript erklärt habe ...

Es gibt eine Möglichkeit, die Datei als Python-Wörterbuch zu importieren.

Oh, als letztes, denke daran, dass ich nicht genau weiß, wie viele Variablen ich in der Textdatei haben würde.

Edit 2: Ich bin an stephans JSON-Lösung sehr interessiert, da auf diese Weise die Textdatei einfach mit anderen Sprachen (PHP, dann über AJAX JavaScript) gelesen werden könnte, was aber fehlschlägt in etwas, während diese Lösung zu handeln:

#for the example, i dont load the file but create a var with the supposed file content
file_content = "'var_a': 4, 'var_b': 'a string'"
mydict = dict(file_content)
#Error: ValueError: dictionary update sequence element #0 has length 1; 2 is required
file_content_2 = "{'var_a': 4, 'var_b': 'a string'}"
mydict_2 = dict(json.dump(file_content_2, True))
#Error:
#Traceback (most recent call last):
#File "<pyshell#5>", line 1, in <module>
#mydict_2 = dict(json.dump(file_content_2, True))
#File "C:\Python26\lib\json\__init__.py", line 181, in dump
#fp.write(chunk)
#AttributeError: 'bool' object has no attribute 'write'

Welche Probleme kann ich mit dem JSON-Format haben? Und wie kann ich ein JSON-Array in einer Textdatei lesen und in ein Python-Diktat umwandeln?

P.S: Ich mag die Lösung nicht, wenn .py-Dateien verwendet werden. Ich ziehe es vor, .txt, .inc, ... zu bevorzugen, was sich nicht auf eine Sprache beschränkt.

34
Strae

Laden Sie Ihre Datei mit JSON oder PyYAML in ein Wörterbuch the_dict (siehe doc für JSON oder PyYAML für diesen Schritt, beide können Datentyp speichern) und fügen Sie das Wörterbuch zu Ihrem Globals-Wörterbuch hinzu, z. mit globals().update(the_dict).

Wenn Sie es stattdessen in einem lokalen Wörterbuch wünschen (z. B. in einer Funktion), können Sie dies folgendermaßen tun:

for (n, v) in the_dict.items():
    exec('%s=%s' % (n, repr(v)))

solange es sicher ist exec zu verwenden. Wenn nicht, können Sie das Wörterbuch direkt verwenden.

14
stephan

Was ich aber sehr lieben werde, ist, mich auf die Variable directeclty zu beziehen, wie ich sie im Python-Skript erklärt habe.

Angenommen, Sie sind froh, Ihre Syntax leicht zu ändern, verwenden Sie einfach Python und importieren Sie das Modul "config".

# myconfig.py:

var_a = 'home'
var_b = 'car'
var_c = 15.5

Dann mach 

from myconfig import *

Und Sie können sie in Ihrem aktuellen Kontext mit Namen referenzieren.

59
hbn

Verwenden Sie ConfigParser.

Ihre Konfiguration:

[myvars]
var_a: 'home'
var_b: 'car'
var_c: 15.5

Ihr Python-Code:

import ConfigParser

config = ConfigParser.ConfigParser()
config.read("config.ini")
var_a = config.get("myvars", "var_a")
var_b = config.get("myvars", "var_b")
var_c = config.get("myvars", "var_c")
24
Igor Krivokon

Sie können behandeln Ihre Textdatei als Python-Modul _ bearbeiten und dynamisch mit imp.load_source laden:

import imp
imp.load_source( name, pathname[, file]) 

Beispiel:

// mydata.txt
var1 = 'hi'
var2 = 'how are you?'
var3 = { 1:'elem1', 2:'elem2' }
//...

// In your script file
def getVarFromFile(filename):
    import imp
    f = open(filename)
    global data
    data = imp.load_source('data', '', f)
    f.close()

# path to "config" file
getVarFromFile('c:/mydata.txt')
print data.var1
print data.var2
print data.var3
...
18

Die anderen hier veröffentlichten Lösungen haben für mich nicht funktioniert, weil: 

  • ich brauchte nur Parameter aus einer Datei für ein normales Skript
  • import * hat für mich nicht funktioniert, da ich eine Möglichkeit brauche, sie durch Auswahl einer anderen Datei zu überschreiben
  • Nur eine Akte mit einem Diktat war nicht in Ordnung, da ich dazu Kommentare brauchte.

So endete ich mit Configparser und globals().update()

Testdatei:

#File parametertest.cfg:
[Settings]
#Comments are no Problem
test= True
bla= False    #Here neither

#that neither

Und das ist mein Demo-Skript:

import ConfigParser

cfg = ConfigParser.RawConfigParser()
cfg.read('parametertest.cfg')       # Read file

#print cfg.getboolean('Settings','bla') # Manual Way to acess them

par=dict(cfg.items("Settings"))
for p in par:
    par[p]=par[p].split("#",1)[0].strip() # To get rid of inline comments

globals().update(par)  #Make them availible globally

print bla

Es ist jetzt nur für eine Datei mit einem Abschnitt, aber das wird leicht zu übernehmen sein.

Hoffe es wird für jemanden hilfreich sein :)

5
SolarSimon

Angenommen, Sie haben eine Datei namens "test.txt" mit:

a=1.251
b=2.65415
c=3.54
d=549.5645
e=4684.65489

Und Sie möchten eine Variable finden (a, b, c, d oder e):

ffile=open('test.txt','r').read()

variable=raw_input('Wich is the variable you are looking for?\n')

ini=ffile.find(variable)+(len(variable)+1)
rest=ffile[ini:]
search_enter=rest.find('\n')
number=float(rest[:search_enter])

print "value:",number
4
JorgeGarza

Wie zuverlässig ist dein Format? Wenn der Separator immer genau ':' ist, funktioniert das Folgende. Wenn nicht, sollte eine vergleichsweise einfache Regex die Arbeit erledigen.

Solange Sie mit relativ einfachen Variablentypen arbeiten, macht die Eval-Funktion von Python das Verweilen von Variablen in Dateien überraschend einfach.

(Im Folgenden finden Sie ein Wörterbuch, das übrigens eine Ihrer bevorzugten Lösungen war).

def read_config(filename):
    f = open(filename)
    config_dict = {}
    for lines in f:
        items = lines.split(': ', 1)
        config_dict[items[0]] = eval(items[1])
    return config_dict
3
mavnn

Was Sie anscheinend wünschen, ist das Folgende, aber dies ist NOT EMPFOHLEN:

>>> for line in open('dangerous.txt'):
...     exec('%s = %s' % Tuple(line.split(':', 1)))
... 
>>> var_a
'home'

Dies führt zu einem ähnlichen Verhalten wie PHP register_globals und hat daher die gleichen Sicherheitsprobleme. Darüber hinaus ermöglicht die Verwendung von exec, das ich gezeigt habe, die Ausführung von beliebigem Code. Nur Verwenden Sie diese Option, wenn Sie absolut sicher sind, dass der Inhalt der Textdatei unter allen Umständen als vertrauenswürdig eingestuft werden kann.

Sie sollten in Erwägung ziehen, die Variablen nicht an den lokalen Bereich, sondern an ein Objekt zu binden, und eine Bibliothek verwenden, die den Inhalt der Datei so analysiert, dass kein Code ausgeführt wird. Also: Gehen Sie zu einer der anderen hier angebotenen Lösungen.

(Bitte beachten Sie: Ich habe diese Antwort nicht als Lösung hinzugefügt, sondern als explizite Nichtlösung.)

1
Stephan202

die Antwort von hbn funktioniert nicht sofort, wenn die zu ladende Datei in einem Unterverzeichnis oder mit Bindestrichen bezeichnet ist.

In einem solchen Fall können Sie diese Alternative in Betracht ziehen:

exec open(myconfig.py).read()

Oder die einfachere, aber in python3 veraltete:

execfile(myconfig.py)

Die Warnung von Stephan202 trifft jedoch auf beide Optionen zu, und möglicherweise ist die Schleife auf Leitungen sicherer.