[英]Python variable scope issue in script
I'm coming across some weirdness with a variable not being accessible in other functions after being set. 设置后,我遇到了一些奇怪的问题,该变量无法在其他函数中访问。 This is a Celery task file named
html.py
这是一个名为
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)
When I call this via 当我通过
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)
the wget process kicks off as expected. wget进程按预期启动。 However, the
base_path
parameter at the top of the file never gets set, so when I call status
via 然而,
base_path
在文件的顶部参数永远不会被设置,所以当我打电话status
通过
status = html.status.delay()
the base_path
variable is an empty string, despite status
being called after download
. 尽管在
download
后调用了status
, base_path
变量还是一个空字符串。 Is this because these tasks are in a script vs a class? 这是因为这些任务在脚本中还是在类中?
Because in function download
at this line 因为在功能上
download
此行
base_path = settings.WGET_PATH + str(cl_id)
you just creates a local variable with name base_path
. 您只需创建一个名称为
base_path
的局部变量。 To avoid it you should declare base_path
in function as global
. 为了避免这种情况,您应该在function中将
base_path
声明为global
。 For example: 例如:
@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)
...
From Python docs : 来自Python 文档 :
At any time during execution, there are at least three nested scopes whose namespaces are directly accessible: 在执行过程中的任何时候,至少有三个嵌套作用域可以直接访问其名称空间:
If a name is declared global, then all references and assignments go directly to the middle scope containing the module's global names. 如果名称被声明为全局名称,则所有引用和赋值将直接转到包含模块全局名称的中间范围。 Otherwise, all variables found outside of the innermost scope are read-only (an attempt to write to such a variable will simply create a new local variable in the innermost scope, leaving the identically named outer variable unchanged).
否则,在最内层作用域之外找到的所有变量都是只读的(尝试写入此类变量只会在最内层作用域内创建一个新的局部变量,而使名称相同的外层变量保持不变)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.