2016-03-23 9 views
2

私は、設定された後、他の関数でアクセスできない変数を使用して奇妙なことに出くわします。これは予想通りwgetのプロセスは、キックオフスクリプト内のPython変数スコープの問題

from ingest.task import html 
web_url = 'https://www.gnu.org/software/wget/manual/html_node/index.html' 
ingest = html.download.delay(web_url, 54321) 

経由

base_path = '' 

@app.task(bind=True) 
def status(self): 
    """ 
    returns the count of files downloaded and the timestamp of the most recently downloaded file 
    """ 

    num_count = 0 
    latest_timestamp = '' 
    for root, _, filenames in os.walk(base_path): 
     for filename in filenames: 
      file_path = root + '/' + filename 
      file_timestamp = datetime.fromtimestamp(os.path.getctime(file_path)) 
      if latest_timestamp == '' or file_timestamp > latest_timestamp: 
       latest_timestamp = file_timestamp 
      num_count += 1 

@app.task(bind = True) 
def download(self, url='', cl_id=-1): 
    if len(url) == 0 or cl_id < 0: 
     return None 

    base_path = settings.WGET_PATH + str(cl_id) 

    log_paths = { 
     'output' : wget_base_path + '/out.log', 
     'rejected' : wget_base_path + '/rejected.log' 
    } 

    create_files(log_paths) 
    wget_cmd = 'wget -prc --convert-links --html-extension --wait=3 --random-wait --no-parent ' \ 
        '--directory-prefix={0} -o {1} --rejected-log={2} {3}'.\ 
     format(wget_base_path, log_paths['output'], log_paths['rejected'], url) 

    subprocess.Popen(wget_cmd, shell = True) 

私はこれを呼び出すhtml.pyという名前セロリタスクファイルです。ただし、ファイルの先頭にbase_pathパラメータが設定れることは決してありませんので、私はstatus

経由
status = html.status.delay() 

を呼び出すときbase_path変数はstatusdownload後に呼び出されているにもかかわらず、空の文字列です。これらのタスクはスクリプト対クラスのためですか?

答えて

4

は、このためライン

base_path = settings.WGET_PATH + str(cl_id) 

の機能downloadにあなただけの名前base_pathのローカル変数を作成します。これを避けるには、をglobalのように宣言する必要があります。たとえば、次のPython docsから

@app.task(bind = True) 
def download(self, url='', cl_id=-1): 
    if len(url) == 0 or cl_id < 0: 
     return None 

    global base_path 
    base_path = settings.WGET_PATH + str(cl_id) 
... 

  • 検索される最も内側のスコープは、:

    実行中の任意の時点で、その名前空間に直接アクセス可能である少なくとも三つの入れ子になったスコープがあります最初にローカル名を含む

  • 最も近い囲みスコープから検索され、非ローカル名でもグローバル名でもない、囲む関数のスコープ
  • 最後からスコープは、現在のモジュールのグローバル名
  • (最後に検索)最も外側のスコープは名前空間は、内蔵含有される名前

名がグローバルに宣言されている場合は、すべての参照が含まれています割り当てはモジュールのグローバル名を含む中間スコープに直接移動します。それ以外の場合は、最も内側のスコープの外にある変数はすべて読み取り専用です(そのような変数に書き込むと、最も内側のスコープに新しいローカル変数が作成され、同じ名前の外部変数は変更されません)。

+0

Hmm、ok。説明ありがとう。さらにJavaの経験は、Pythonで私を驚かせてくれます。 – Jason

関連する問題