循环示例

时间:2016-04-09 19:21:42

标签: python

我是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__内是一个接一个。我的问题是:在那个重复的代码我是否需要给新名称archiveidfilefilesoutfile的变量?是否会发生冲突?是否有任何良好做法关注点?

2 个答案:

答案 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的示例!

  

是否有任何良好做法需要牢记在心?

有可能陷入舆论领域:

  • 您很少在循环外使用循环变量的值。所以通常通常在函数后面的新循环中再次使用相同的循环变量,但通常你应该检查函数之前的所有对该变量名的使用再次使用它,确定。对于模块级代码,情况更糟:在添加第二个循环之前,您需要确保模块的外部用户不依赖于具有第一个循环留在其中的值的变量。
  • 除非对象在两个不同的位置提供 exact 相同的角色,否则虽然稍后在函数中重用一个变量是安全的,但它仍然会有点混乱。
  • 显然,在将代码复制粘贴两次到函数之前,您希望合理地确定在您的特定情况下,重复(可能有一些更改)确实比定义另一个函数并调用它两次更好。

答案 1 :(得分:3)

通常,缩进块不会启动新范围。只有模块,类和函数定义新的范围。 (好吧,差不多。在Python 3中,list / set / dict理解中的索引是理解的局部。)

在您的示例中,例如,archivewith语句发生的整个模块/类/函数的范围内,与with语句体内的任何变量一样。 {1}}陈述。如果with语句位于模块范围,则所有赋值都是模块全局变量。如果它位于类定义的顶层,则它们都是类属性。如果它(很可能)在函数或方法声明中定义,则它们是该函数的本地。