2016-08-18 6 views
1

私はサブ関数を持つ関数を持っており、サブ関数内の変数を初期化したいと思います。単純に、関数内の変数(サブ関数)を変数ファイル名のファイルから設定する

file = "foo" 
def outerFunction(): 
    def innerFunction(): 
     var1 = 0 
     var2 = 1 
     var3 = 2 
     print file, var1, var2, var3 
    file = "bar" 
    innerFunction() 
outerFunction() 

出力:bar 0 1 2

はしかし、私は、複数の異なるファイル内の変数のかなりの数が多いと私は単にサブ関数が呼び出されるサブ関数にインポートしたいと思います。私は、次の内容のファイルbar.pyあるとします。

var1=0 
var2=1 
var3=2 

をその後、私はときのPython 2.7がそれを好きではないので、これはエラーになるために起こっている

file = "foo" 
def outerFunction(): 
    def innerFunction(): 
     from file import * 
     print file, var1, var2, var3 
    file = "bar" 
    innerFunction() 
outerFunction() 

ことに私のコードを変更しますサブ関数内にimportを使用してください。だから、代わりに、我々は直接__import__機能を使用することができます。

file = "foo" 
def outerFunction(): 
    def innerFunction(): 
     __import__(file) 
     print file, var1, var2, var3 
    file = "bar" 
    innerFunction() 
outerFunction() 

ここインポート方法は動作しますが、変数は、これまで実際に私は、印刷に行くときにエラーが生じ、サブファンクションの変数リストにそれをしないでくださいそれらを出す。今、私はコードを変更できることを知っています

file = "foo" 
def outerFunction(): 
    def innerFunction(): 
     f = __import__(file) 
     print file, f.var1, f.var2, f.var3 
    file = "bar" 
    innerFunction() 
outerFunction() 

そしてpeachyが動作します。しかし、それは私が探している解決策ではありません。私は、残りのコードを変更せずにそれらの関数をインポートできるようにしたい。この問題の解決策はありますか?

+0

なぜファイルやオブジェクトを作成してインスタンス化できないのですか?次に、単にfile.property(file.var1)を実行するか、計算を実行したい場合はgetter関数を使用することもできます。 – kyle

+0

あなたはPythonのインポートシステムについていくらか混乱しているようです。 「Python 2.7では、サブ関数内でインポートを使用すると、Python 2.7が好きではありません。いいえ...Pythonでは、どのバージョンでもスコープに関係なくimportステートメントで変数を使用することはできません。 "ここでのインポート方法は機能しますが、変数はローカルスコープに追加されません。"まあ、いいえ、それはどのような状況でも 'import x'がどのように動作するかではありません。私はあなたの第3のポイントを本当に理解していません。 –

+2

また、それらが単なる設定であれば、それらを "実行"する代わりに解析する必要があります。たとえば、[configparser](https://docs.python.org/3/library/configparser.html)を使用すると、 – spectras

答えて

0

保守性の観点からは、モジュールをインポートしてからモジュールの変数を参照するのが最適です。変数がどこから来たのかを見るのは簡単です。

from module import *は、特に複数のモジュールに同じ名前の変数が含まれている場合、変数がどこから来たのかを調べにくいため、悩まされます。 from module import *は、ローカル変数がPythonでどのように機能するかによって、関数内では不可能です。ローカル変数はスタックに格納され、Pythonがいくつの変数があるか分からなければ、スタック上に適切に領域を割り当てることができません。

しかし、それはあなたが求めていることをすることができます。しかし、あなたはすべきではありません。この背後にある考え方は、グローバル変数として参照された変数を残し、関数が開始されるときにそれに応じてグローバル変数を更新することです。例えば。

from importlib import import_module 

file_ = "foo" 
def outer(): 
    def inner(): 
     m = import_module(file_) # import module whose name is the contents of file_ 
     globals().update(m.__dict__) # add module's globals to our own 
     print(file_, var0, var1, var2) 
    file_ = "bar" 
    inner() 
outer() 

各内部関数はグローバルの同じセットを共有することになりますし、可能な同じ名前の変数を上書きすることがあり、これは恐ろしい考えです。これは、inner関数が同時に実行された場合、またはouterを定義したモジュールで必要な変数を上書きする場合に問題を引き起こします。各inner関数を独自のグローバルセットを使用するように変更することでこれを克服することは可能ですが、これは恐ろしいハックであり、主にこれがどのように可能かを示すために含まれています。

from importlib import import_module 
from types import FunctionType 

file_ = "foo" 
def outer(): 
    def inner(): 
     m = import_module(file_) 
     globals().update(m.__dict__) 
     print(file_, var0, var1, var2) 
    # redefine inner with new globals 
    inner = FunctionType(inner.__code__, 
     dict(import_module=import_module, __builtins__=__builtins__), # new globals 
     inner.__name__, inner.__defaults__, inner.__closure__ 
    ) 
    file_ = "bar" 
    inner() 
outer() 
関連する問題