簡體   English   中英

腳本中的Python變量范圍問題

[英]Python variable scope issue in script

設置后,我遇到了一些奇怪的問題,該變量無法在其他函數中訪問。 這是一個名為html.py的Celery任務文件

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)

當我通過

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)

wget進程按預期啟動。 然而, base_path在文件的頂部參數永遠不會被設置,所以當我打電話status通過

status = html.status.delay()

盡管在download后調用了statusbase_path變量還是一個空字符串。 這是因為這些任務在腳本中還是在類中?

因為在功能上download此行

base_path = settings.WGET_PATH + str(cl_id)

您只需創建一個名稱為base_path的局部變量。 為了避免這種情況,您應該在function中將base_path聲明為global 例如:

@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)
...

來自Python 文檔

在執行過程中的任何時候,至少有三個嵌套作用域可以直接訪問其名稱空間:

  • 最里面的作用域(首先搜索)包含本地名稱
  • 從最接近的封閉范圍開始搜索的任何封閉函數的范圍都包含非本地名稱,也包含非全局名稱
  • 倒數第二個范圍包含當前模塊的全局名稱
  • 最外面的范圍(最后搜索)是包含內置名稱的名稱空間

如果名稱被聲明為全局名稱,則所有引用和賦值將直接轉到包含模塊全局名稱的中間范圍。 否則,在最內層作用域之外找到的所有變量都是只讀的(嘗試寫入此類變量只會在最內層作用域內創建一個新的局部變量,而使名稱相同的外層變量保持不變)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM