Reputation:
I am new with Python and confused regarding the scope of variables which are declared inside loops. I have seen some examples but it is hard for me to understand it in my specific case.
For example, I saw the following code segment 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)
I basically have the above code repeated in very much the same way but with different statements executed inside the loops. These similar code segments are one after the other inside my __main__
. My question is: in that repeated code do I need to give new names to the variables for archive
, id
, file
, files
, outfile
or not? Will there be a clash or something? Are there any good-practice concerns to keep in mind?
Upvotes: 1
Views: 1587
Reputation: 279225
Assuming this code is in a function then the scope of the variables is to the end of the function. If this code is at module-level then the scope of the variables is the module (aka global) scope.
You don't have to use different names. The following code will merely assign different objects to the archive
variable at different times:
with ZipFile(self.archive_name, "r") as archive:
print(id(archive))
with ZipFile(self.archive_name, "r") as archive:
print(id(archive))
It's equivalent to this:
archive = ZipFile(self.archive_name, "r")
with archive:
print(id(archive))
archive = ZipFile(self.archive_name, "r")
with archive:
print(id(archive))
That is to say, the blocks associated with with
statements and loops don't define a scope so far as variables are concerned, they are "just" assignments. You should see two different values printed for the ids of the different objects.
Beware that since your sample code uses id
as a variable name, my example using the built-in function id
should be used with care!
Are there any good-practice concerns to keep in mind?
At risk of straying into opinionated territory:
Upvotes: 1
Reputation: 530902
In general, an indented block does not start a new scope. Only modules, classes, and functions define new scopes. (Well, almost. In Python 3, the indices in a list/set/dict comprehension are local to the comprehension.)
In your example, for instance, archive
is in scope for the entire module/class/function in which the with
statement occurs, as are any variable first assigned to within the body of the with
statement. If the with
statement is at module scope, then all assignments are to module globals. If it is at the top level of a class definition, they are all class attributes. If it is (as is likely) defined in a function or method declaration, then they are local to that function.
Upvotes: 1