web-dev-qa-db-ja.com

テキストファイルから変数値を取得する最良の方法-Python-Json

この質問 を参照すると、似たような問題がありますが、同じ問題はありません。

途中で、次のような構造のテキストファイルを作成します。

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

そして、私はそれを必要としますpythonファイルを読み取り、値が 'home'であるvar_aという名前の変数を作成します。

例:

#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.

これは可能ですか、つまり、var型を保持することもできますか?

テキストファイルの構造には完全に自由があることに注意してください。提案したものが最適でない場合は、好きな形式を使用できます。

[〜#〜] edit [〜#〜]:ConfigParserは解決策になる可能性がありますが、私はあまり好きではありません。スクリプトを使用して、ファイル内の変数を参照する必要があります

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

しかし、私が好きなのは、pythonスクリプトで宣言したように、変数を直接参照することです...

python辞書としてファイルをインポートする方法がありますか?

ああ、最後に、テキストファイルにいくつの変数があるか正確にはわからないことに注意してください。

編集2:私はステファンのJSONソリューションに非常に興味があります。その方法で、テキストファイルは他の言語(PHP、 AJAX JavaScript)、しかし、私はその解決策を実行中に何かに失敗します:

#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'

JSON形式ではどのような問題に該当しますか?そして、どのようにテキストファイルのJSON配列を読み取り、python dict?

追伸:.pyファイルを使用したソリューションは好きではありません。 .txt、.inc、.whatは1つの言語に制限されないものを好むでしょう。

36
Strae

[〜#〜] json [〜#〜] または PyYAML を使用してファイルを辞書にロードします_the_dict_(このステップについてはJSONまたはPyYAMLのドキュメントを参照してください。両方ともデータ型を保存できます)、辞書をグローバル辞書に追加します、例えばglobals().update(the_dict)を使用します。

代わりにローカル辞書に(関数内などで)必要な場合は、次のように実行できます。

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

execを使用しても安全である限り。そうでない場合は、辞書を直接使用できます。

14
stephan

しかし、pythonスクリプトで宣言したように、変数direcltyを参照するのが好きです。

構文をわずかに変更しても問題ない場合、pythonを使用して「config」モジュールをインポートします。

# myconfig.py:

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

それから

from myconfig import *

また、現在のコンテキストで名前で参照できます。

61
hbn

ConfigParserを使用します。

あなたの設定:

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

あなたのpythonコード:

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

テキストファイルをtreatpythonモジュールとして扱い、 imp.load_source

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

例:

// 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
...
23

ここに投稿された他のソリューションは、私にとってはうまくいきませんでした:

  • 私は通常のスクリプト用のファイルからパラメータが必要でした
  • _import *_は機能しませんでした。別のファイルを選択して上書きする方法が必要なためです
  • コメントが必要だったので、辞書のあるファイルだけでは問題ありませんでした。

だから私はConfigparserglobals().update()を使用することになりました

テストファイル:

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

#that neither
_

それが私のデモスクリプトです。

_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
_

現在は1つのセクションを持つファイル用ですが、簡単に採用できます。

それが誰かに役立つことを願っています:)

5
SolarSimon

「test.txt」というファイルがあり、次のファイルがあるとします。

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

そして、変数(a、b、c、dまたは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

あなたのフォーマットはどれくらい信頼できますか?セパレーターが常に正確に「:」の場合、次のように機能します。そうでなければ、比較的単純な正規表現が仕事をするはずです。

かなり単純な変数タイプで作業している限り、Pythonのeval関数を使用すると、ファイルへの変数の永続化が驚くほど簡単になります。

(以下は、btwという辞書を示していますが、これはあなたが好む解決策の1つであると述べました)。

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

あなたが望むように見えるものは次のとおりですが、これはNOT RECOMMENDEDです:

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

これにより、PHPの register_globals なので、同じセキュリティ問題があります。さらに、私が示したexecを使用すると、任意のコードを実行できます。 Onlyテキストファイルの内容がすべての状況下で信頼できると確信できる場合にのみこれを使用します。

変数をローカルスコープではなくオブジェクトにバインドすることを実際に検討し、コードが実行されないようにファイルの内容を解析するライブラリを使用する必要があります。だから:ここで提供されている他のソリューションのいずれかで行く。

(注意:この回答はソリューションとしてではなく、明示的なnon-solutionとして追加しました。)

1
Stephan202

ロードするファイルが サブディレクトリにある または ダッシュで名前が付けられている の場合、hbnの答えはそのままでは機能しません。

このような場合、この代替案を検討することができます:

exec open(myconfig.py).read()

または、python3でよりシンプルですが非推奨:

execfile(myconfig.py)

ただし、Stephan202の警告は両方のオプションに当てはまると思いますし、行のループの方が安全かもしれません。