web-dev-qa-db-ja.com

ファイル間でグローバル変数を使用しますか?

グローバル変数がどのように機能するかについて少し混乱しています。私は約50のファイルを持つ大規模なプロジェクトを持っています、そして私はそれらすべてのファイルに対してグローバル変数を定義する必要があります。

次のように、私のプロジェクトのmain.pyファイルでそれらを定義しました。

# ../myproject/main.py

# Define global myList
global myList
myList = []

# Imports
import subfile

# Do something
subfile.stuff()
print(myList[0])

次のようにsubfile.pymyListを使用しようとしています

# ../myproject/subfile.py

# Save "hey" into myList
def stuff():
    globals()["myList"].append("hey")

他の方法で試したが、うまくいかなかった

# ../myproject/main.py

# Import globfile    
import globfile

# Save myList into globfile
globfile.myList = []

# Import subfile
import subfile

# Do something
subfile.stuff()
print(globfile.myList[0])

そしてsubfile.pyの中に私はこれを持っていました:

# ../myproject/subfile.py

# Import globfile
import globfile

# Save "hey" into myList
def stuff():
    globfile.myList.append("hey")

しかし、やはり、うまくいきませんでした。これをどのように実装すればよいですか。 2つのファイルが実際にはお互いを知らない場合(サブファイルがメインを知らない場合)、そのように機能することはできませんが、io writingやpickleを使用せずにその方法を考えることができないやりたくない。

147
user1632861

問題はmain.pyからmyListを定義したことですが、subfile.pyはそれを使う必要があります。これはこの問題を解決するためのきれいな方法です:すべてのグローバルをファイルに移動し、私はこのファイルをsettings.pyと呼びます。このファイルは、グローバルの定義とそれらの初期化を担当します。

# settings.py

def init():
    global myList
    myList = []

次に、あなたのsubfileはグローバルをインポートすることができます:

# subfile.py

import settings

def stuff():
    settings.myList.append('hey')

subfileinit()を呼び出さないことに注意してください - そのタスクはmain.pyに属します:

# main.py

import settings
import subfile

settings.init()          # Call only once
subfile.stuff()         # Do stuff with global var
print settings.myList[0] # Check the result

これにより、グローバル変数を2回以上初期化しないで目的を達成できます。

252
Hai Vu

モジュール間でグローバル変数を共有する に関するPythonの文書を参照してください。

単一のプログラム内でモジュール間で情報を共有するための標準的な方法は、特別なモジュール(多くの場合、configまたはcfgと呼ばれる)を作成することです。

config.py:

x = 0   # Default value of the 'x' configuration setting

アプリケーションのすべてのモジュールにconfigモジュールをインポートしてください。その後、モジュールはグローバル名として使用可能になります。

main.py:

import config
print config.x

または

from config import x
print x

これはまたあなたにsetそのような変数動的にをさせるでしょう:

import config
config.x = my_function

一般に、modulename import *からを使用しないでください。そうすると、輸入者の名前空間が乱雑になり、リンターが未定義の名前を検出するのがはるかに困難になります。

57
Ogaga Uzoh

あなたはPythonのグローバル変数を「モジュール」変数と考えることができます - そしてそのようにそれらはCからの伝統的な「グローバル変数」よりはるかに有用です。

グローバル変数は実際にはモジュールの__dict__で定義されており、そのモジュールの外部からモジュール属性としてアクセスできます。

だから、あなたの例では:

# ../myproject/main.py

# Define global myList
# global myList  - there is no "global" declaration at module level. Just inside
# function and methods
myList = []

# Imports
import subfile

# Do something
subfile.stuff()
print(myList[0])

そして:

# ../myproject/subfile.py

# Save "hey" into myList
def stuff():
     # You have to make the module main available for the 
     # code here.
     # Placing the import inside the function body will
     # usually avoid import cycles - 
     # unless you happen to call this function from 
     # either main or subfile's body (i.e. not from inside a function or method)
     import main
     main.mylist.append("hey")
20
jsbueno

from your_file import *を使用すると問題が解決するはずです。グローバルに利用できるようにすべてを定義しています(もちろんインポート内のローカル変数を除く)。

例えば:

##test.py:

from pytest import *

print hello_world

そして:

##pytest.py

hello_world="hello world!"
12
IT Ninja

Hai Vuの答えは、1つのコメントだけでうまくいきます。

他のモジュールでグローバルを使用していて、グローバルを動的に設定したい場合は、グローバル変数を設定した後に他のモジュールをインポートするように注意してください。

# settings.py
def init(arg):
    global myList
    myList = []
    mylist.append(arg)


# subfile.py
import settings

def print():
    settings.myList[0]


# main.py
import settings
settings.init("1st")     # global init before used in other imported modules
                         # Or else they will be undefined

import subfile    
subfile.print()          # global usage
8
lastboy

あなたの2回目の試みは完全にうまくいくでしょう、そして実際にあなたがグローバルに利用可能にしたい変数名を扱うための本当に良い方法です。しかし、最後の行に名前の誤りがあります。これはどうあるべきかです:

# ../myproject/main.py

# Import globfile    
import globfile

# Save myList into globfile
globfile.myList = []

# Import subfile
import subfile

# Do something
subfile.stuff()
print(globfile.myList[0])

最後の行を見ますか? myListはglobfileの属性であり、サブファイルではありません。これはあなたが望むように働くでしょう。

マイク

4
MikeHunter