繁体   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