2016-11-07 13 views
0

ここにはこれらの質問がいくつかありますが、私が後にしているものと一致しないものは見つかりませんでした。pythonグローバル変数スコープの混乱。これらの変数は何にアクセスできないのですか?

私は共通のファイルを持っています。tools.pyと呼ぶことができます。このファイルでは、私が使用するパス定義のホストとコマンドラインの引数に応じて、いくつかのキーのパスを設定するinit_paths機能があります。

def init_paths(args): 
    global tools_dir, tools_src, tools_bin 

    if args.tools_set: 
     tools_dir = os.path.realpath(os.path.join(args.tools_set,"tools")) 
    else: 
     tools_dir = os.path.join(BAR_PATH, "tools") 

FOO_PATH = os.path.realpath(os.path.join(os.path.dirname(os.path.realpath(__file__)), "..")) 
BAR_PATH = os.path.join(FOO_PATH, "foobar") 
tools_dir = none 
tools_src = none 
tools_bin = none 

などを...

私はメインのファイルを持って、通話をすることができます私はどこでこれらを使用したいのですか?

if __name__ == "__main__": 
    args = parseArgs() 
    from tools import init_paths 
    init_paths(args) 
    doStuffFunction(args.one, args.two, args.three) 

私は肉とジャガイモを除外しましたが、これは私のグローバルなスコープの問題を説明するのに十分であると思います。私がこれを実行すると:doStuffFunction()で後で使用したいいくつかのキーパスを設定するために、python main.py --tools-set=/path/to/toolsをinit_pathsへの呼び出しを期待しています。

def doStuffFunction(): 
    searchPath = os.path.join(tools_dir, "folder") 

これは失敗します:はAttributeError: 'をNoneType' オブジェクトは、それがセットになっていないので、これはかなり確信し

endswith何の属性を持っていません。しかし、なぜ?

EDIT

main.py

#!/usr/bin/env python 
import sys 
import os 
import argparse 
import glob 
from tools import * 


def parseArgs(): 
    parser = argparse.ArgumentParser(description="parse my args") 
    parser.add_argument("--toolchain-root", type=str,default=None,help='specify toolchain directory') 
    args = parser.parse_args() 

    return args 


def doStuffFunction(): 
    output = 'output' 
    if not os.path.isdir(output): 
     os.makedirs(output) 
    gimmySugar(output) 

def gimmySugar(output): 
    fileList = [] 
    linkBook= {} 

    searchPath = os.path.join(tools_BIN_ROOT,'gcc-4.8.5') 
    for root, dirs, files in os.walk(searchPath): 
     for libFile in glob.glob(root+'/*.so*'): 
      fileList.append(libFile) 
      if os.path.islink(libFile): 
       linksWith = os.readlink(libFile) 
       linkBook[libFile] = linksWith 

if __name__ == "__main__": 
    # script was called directly from the command line 
    args = parseArgs() 
    from tools import init_settings 
    init_settings(args) 
    doStuffFunction() 

tools.py

import os 

def init_settings(args): 
    global tools_DIR, tools_SRC_ROOT, tools_OBJ_ROOT, tools_BIN_ROOT 
    if args.toolchain_root: 
     tools_DIR = os.path.realpath(os.path.join(args.toolchain_root, "toolchain")) 
    else: 
     tools_DIR = os.path.join(USER_DIR, "") 
    tools_SRC_ROOT = os.path.join(tools_DIR, "src") 
    tools_OBJ_ROOT = os.path.join(tools_DIR, "obj") 
    tools_BIN_ROOT = os.path.join(tools_DIR, "bin") 


ROOT_PATH = os.path.realpath(os.path.join(os.path.dirname(os.path.realpath(__file__)), "..")) 
OUTPUT_PATH = os.path.join(ROOT_PATH, "outputs") 
BUILD_PATH = os.path.join(OUTPUT_PATH, "build") 
USER_DIR = "/usr/lib64/" 
tools_DIR = None 
tools_SRC_ROOT = None 
tools_OBJ_ROOT = None 
tools_BIN_ROOT = None 
+0

'NONE'(は、私は強くconfigまたはOOPであなたのコードをリファクタリングすることをお勧めいたします)有効なpythonではありません、 'None'です。あなたがしていることを100%反映していないコードを分析するのは役に立たない。 –

+0

"グローバル"変数は実際にはPythonのモジュールレベルです。 'tools.init_paths'は' tools'モジュールでグローバルを設定します。インポートするモジュールではありません。 – user2357112

+0

オリジナルのプログラムを、可能な限り最小の**完全**プログラムに縮小してください。あなたの質問を編集して、短いプログラム全体をあなたの質問にコピー&ペーストしてください。詳細は、[mcve]を参照してください。 –

答えて

1
#This line will failed 
searchPath = os.path.join(tools_BIN_ROOT,'gcc-4.8.5') 

は、グローバル変数のスコープは、モジュールレベルで、tools_BIN_ROOTを介さずに共有されることはありませんモジュール間で

tools_BIN_ROOTは、のツールキットにのみグローバル変数です。代わりに、のmain.pyには、のツールキットにはグローバル変数が含まれていません。

これを調べるには、両方のファイルにprint(globals())を使用できます。


Do not use global variable if possible.

これは単純な回避策です。

tools.py

def get_tools_BIN_ROOT(): 
    return tools_BIN_ROOT 

os.py

from tools import get_tools_BIN_ROOT 
searchPath = os.path.join(get_tools_BIN_ROOT(),'gcc-4.8.5') 
+0

シンプルなソリューションをありがとう!私はグローバルがモジュールレベルのみであることを理解しています。再度、感謝します。 –

関連する問題