まず、現在実行中のスクリプト名を取得するために、またはあなたの関数を呼び出したモジュールむしろ、あなたがそれをピックアップする必要がありますスタックトレースから取得します。 globals()
の場合も同じです。writeToValues()
と同じコンテキストで実行されるので、 'caller'からglobals()
を取得することはありません。あなたがinspect
モジュールを使用することができることを解決するには:
import inspect
import os
def writeToValues(name):
caller = inspect.getmodule(inspect.stack()[1][0])
caller_globals = caller.__dict__ # use this instead of globals()
fileName = os.path.splitext(os.path.basename(caller.__file__))[0]
# etc.
これは、あなたのスクリプトをインポートし、その中writeToValues()
を呼び出しているモジュールの名前を取得していることを確認します。
使用可能なPythonファイルを作成する場合、非常に悪い考えです。スクリプト名に空白(例のように)が含まれていれば、スペースで変数名が書き込まれます。結果のファイルをPythonインタプリタにロードしようとすると、エラーが発生します。
第2に、すべてのものの名前でふわふわして、変数名を見つけるために逆引き参照をしようとしているのですか?あなたはことを知っている:
a = 2
b = 2
ab = 5
writeToValues(b)
が{"ab": 2}
を書きますし、それが正しい、などの状態表現(間違った値を保存します)目的で不正な(間違ったVARを節約できます)、両方作っていない{"b": 2}
?変数を渡して、適切なプロパティを確実に取得できるように保存/更新してください。
アップデートの問題はより問題になります。単にファイルを追加するだけでなく、ファイルを更新する必要があります。つまり、現在のスクリプトの行を見つけて削除し、同じ名前の新しいdictをその場所に書き込む必要があります。ファイルが膨大な割合で成長すると思わない場合(つまり、あなたの現在のスクリプトに一致する行を除いて、それを読むよう
import os
import inspect
def writeToValues(name):
caller = inspect.getmodule(inspect.stack()[1][0])
caller_globals = caller.__dict__ # use this instead of globals()
caller_name = os.path.splitext(os.path.basename(caller.__file__))[0]
# keep 'mydict' list in the caller space so multiple callers can use this
target_dict = caller_globals['mydict'] = caller_globals.get('mydict', {})
if name not in caller_globals: # the updated value no longer exists, remove it
target_dict.pop(name, None)
else:
target_dict[name] = caller_globals[name]
# update the 'values.py':
# optionaly check if you should update - if values didn't change no need for slow I/O
with open("values.py", "a+") as f:
last_pos = 0 # keep the last non-update position
while True:
line = f.readline() # we need to use readline() for tell() accuracy
if not line or line.startswith(caller_name): # break at the matching line or EOF
break
last_pos = f.tell() # new non-update position
append_data = f.readlines() # store in memory the rest of the file content, if any
f.seek(last_pos) # rewind to the last non-update position
f.truncate() # truncate the rest of the file
f.write("".join((caller_name, " = ", str(target_dict), "\n"))) # write updated dict
if append_data: # write back the rest of the file, if truncated
f.writelines(append_data)
return target_dict
は、そうでない場合は、すべてを書くために一時ファイルを使用して、追加:とすることをあなたが快適)ワーキングメモリに部分的にそれを持っている、あなたが行うことができます現在のスクリプトの新しい値を削除し、元のファイルを削除して、一時ファイルの名前をvalues.py
に変更します。
だから今、あなたはvalue_writter.py
、たとえば、上記を保存して、スクリプトmy_script.py
でそれを使用する場合:あなたはそれがインポートする任意のスクリプトのために行く必要があります
import value_writter
a = 2
b = 3
value_writter.write_to_values("a")
value_writter.write_to_values("b")
a = 5
value_writter.write_to_values("a")
# values.py contains: my_script = {"a": 5, "b": 3}
同じ。さて、ロック機構なしで同じファイルを複数のスクリプトで編集することは、起こるのを待っている事故ですが、それはまったく別の話です。
また、値が複雑な場合は、システムが壊れてしまいます(または、あなたのdictの出力が正しく表示されません)。自分自身に好意を持ち、いくつかの適切なシリアライゼーションを使用しても、恐ろしいpickle
がこれよりも優れています。
もしもその別のスクリプトがPythonでもあれば、あなたは典型的なものがありません:もし__name__ == "__main__"ならば、 – Drako