web-dev-qa-db-ja.com

ロードpython実行時のコード

実行時に.pyファイルをロードしたいと思います。この.pyファイルは、基本的に次の形式の構成ファイルです。

var1=value  
var2=value  
predicate_function=func line : <return true or false>  

このファイルがロードされたら、var1var2、およびpredicate_functionにアクセスできるようにしたいと思います。各行について、それを述語関数に渡し、falseが返された場合は、無視します。

いずれにせよ、実行時にpythonファイルをロードして、その変数にアクセスする方法がわかりません。

明確化:メインプログラムに渡す必要のあるこれらの構成ファイルはいくつあってもかまいませんが、実行時までそれらの名前はわかりません。グーグルは私に__import__を使うべきだと言っています。そのメソッドを正しく使用して、インポートされたファイルの変数にアクセスする方法がわかりません。

17
Shahbaz

インポートを動的に指定してから、変数を動的に取得できる必要があります。

設定ファイルがbar.pyで、次のようになっているとします。

x = 3
y = 4
def f(x): return (x<4)

次に、コードは次のようになります。

import sys

# somehow modnames should be a list of strings that are the names of config files
#
# you can do this more dynamically depending on what you're doing                                                                                                     
modnames = ['bar']

for modname in modnames:
  exec('import %s' % modname)

for modname in modnames:
  mod = sys.modules[modname]
  for k in mod.__dict__:
    if k[:2] != '__':
      print modname, k, mod.__dict__[k]

私はこの出力を取得します:

bar f <function f at 0x7f2354eb4cf8>
bar x 3
bar y 4

そうすれば、少なくともすべての変数と関数が得られます。述語関数から必要なものを完全に取得できませんでしたが、今は自分で取得できるかもしれません。

10
forefinger

python公式ドキュメント に書かれているように、モジュールを名前でインポートしたい場合は、sys.modulesを使用した後に__import__辞書で検索できます。

構成がmyproject.mymoduleにあるとすると、次のようになります。

module_name = 'myproject.mymodule'

import sys
__import__(module_name)
mymodule = sys.modules[module_name]

# Then you can just access your variables and functions
print mymodule.var1
print mymodule.var2
# etc...

__import__ステートメントの戻り値を使用することもできますが、完全に理解する必要があります python名前空間とスコープでどのように機能するか

14
Clément

インポートされたモジュールが通常の検索パス上にある場合は、 __import__

ファイルシステムの任意のパスからモジュールをロードする必要がある場合は、 imp.load_module

ユーザー指定の任意のコードをロードすることによるセキュリティへの影響を必ず考慮してください。

7
oefe

別のPythonモジュールにアクセスするには、インポートexecfileは数人の人から言及されていますが、面倒で危険です。execfileは名前空間を乱雑にし、場合によっては混乱させることさえあります。実行しているコードをアップします。別のPythonソースファイルにアクセスする場合は、importステートメントを使用します。

さらに良いのは、構成にPythonファイルを使用するのではなく、組み込みモジュールConfigParserまたはJSONなどのシリアル化形式を使用することです。この方法では、構成ファイルでの実行が許可されません。任意の(おそらく悪意のある)コードであり、プログラムを構成するためにPython)を知っている必要はなく、プログラムで簡単に変更できます。

7
Mike Graham

Python _2.*_、 execfile で動作します(特定の辞書を渡し、そこから変数にアクセスすることをお勧めします-ドキュメントのメモにあるように、execfileは呼び出し元の関数のlocals()ディクショナリに影響を与えることはできません)。

Python _3.*_では、execfileが削除されているため、代わりに次のようにします。

_with open('thefile.py') as f:
  exec(f.read(), somedict)
_
2
Alex Martelli

私はパーティーに少し遅れていますが、それでも別の答えを提示したいと思います。

グローバルモジュールの名前空間に影響を与えずにコードをインポートする場合は、匿名モジュールを作成し(types.ModuleTypeを使用)、任意のコードをロードします(compileおよびexecを使用)。たとえば、次のようになります。

import types

filename = "/path/to/your/file.py"
with open(filename) as fp:
    code = compile(fp.read(), filename, "exec")
config_module = types.ModuleType("<config>")
exec code in config_module.__dict__

その後、config_module.var1、&cとして変数にアクセスできます。

2
Dolda2000

プログラムが実行されていないときにのみユーザーが編集する構成ファイルが必要な場合は、通常のpythonファイルとしてインポートするだけです。

すなわち。

main.py:

import config
print config.var1

config.py:

var="var12"
var2 = 100.5
1
Simon Callan

impモジュールを試してください: http://docs.python.org/library/imp.html

0
dzen

Pythonバージョンが明確に言及されていないため、impモジュールが非推奨になったことを指摘する価値があります新しいPythonバージョンでは importlib モジュールを優先します。 例ここに。

0
Tom