我是Python新手,对于在循环内声明的变量范围感到困惑。我看过一些例子,但在我的具体情况下,我很难理解它。
例如,我看到了以下代码段here:
with ZipFile(self.archive_name, "r") as archive:
for id, files in data.items():
if files:
print("Creating", id)
dirpath = os.path.join(directory, id)
os.mkdir(dirpath)
for file in files:
match = pattern.match(filename)
new = match.group(2)
new_filename = os.path.join(dirpath, new)
content = archive.open(file).read()
with open(new_filename, "wb") as outfile:
outfile.write(content)
我基本上以非常相同的方式重复上面的代码重复,但在循环中执行了不同的语句。 这些类似的代码段在我的__main__
内是一个接一个。我的问题是:在那个重复的代码我是否需要给新名称archive
,id
,file
,files
,outfile
的变量?是否会发生冲突?是否有任何良好做法关注点?
答案 0 :(得分:3)
假设此代码在函数中,则变量的范围是函数的末尾。如果此代码位于模块级别,则变量的范围是模块(也称为全局)范围。
您 不能使用不同的名称。以下代码将仅在不同时间为archive
变量分配不同的对象:
with ZipFile(self.archive_name, "r") as archive:
print(id(archive))
with ZipFile(self.archive_name, "r") as archive:
print(id(archive))
它等同于:
archive = ZipFile(self.archive_name, "r")
with archive:
print(id(archive))
archive = ZipFile(self.archive_name, "r")
with archive:
print(id(archive))
也就是说,与with
语句和循环相关联的块在变量方面没有定义范围,它们只是“正义”赋值。您应该看到为不同对象的ID打印了两个不同的值。
请注意,由于您的示例代码使用id
作为变量名,因此应谨慎使用我使用内置函数id
的示例!
是否有任何良好做法需要牢记在心?
有可能陷入舆论领域:
答案 1 :(得分:3)
通常,缩进块不会启动新范围。只有模块,类和函数定义新的范围。 (好吧,差不多。在Python 3中,list / set / dict理解中的索引是理解的局部。)
在您的示例中,例如,archive
在with
语句发生的整个模块/类/函数的范围内,与with
语句体内的任何变量一样。 {1}}陈述。如果with
语句位于模块范围,则所有赋值都是模块全局变量。如果它位于类定义的顶层,则它们都是类属性。如果它(很可能)在函数或方法声明中定义,则它们是该函数的本地。