Area of visibility in python 3

by Alex
Area of visibility in python 3

The scope of variables in the Python programming language is a kind of namespace within which created objects operate. This feature allows you to restrict access to certain values to avoid conflicts between identifiers that are the same. Variables come in two varieties: local and global, which in most cases is determined by where they are first identified in the program.

Local variables

To create variables that have a local scope, you just need to put them in a separate block of code, isolated from the rest of the program. To see a local variable in action, you simply initialize an integer object with the name x and the value 100 in the function f, as in the following example

def f():
    x = 100
    print(x)
f()

100

Here x has a local scope because it is only available within its function f. By calling this function from the external part of the program, you can see the output of an integer value on the screen. However, if you try to print x outside the scope of function f, the compiler will immediately generate an error

def f():
    x = 100
    print(x)
f()
print(x)

100
Traceback (most recent call last):
  File "main.py", line 5, in <module>
    print(x)
NameError: name 'x' is not defined
This is because the external part of the program knows nothing about the x variable, because it contains a completely different namespace. Local objects can only be used in the area where they have been identified. Otherwise, the compiler will report an error if it cannot find the variable it needs.

Global Variables

To be able to use a value in any part of your program, you must declare a global variable. To do this, you have to create a variable separate from the code area that is limited to a certain code block, such as a function. The following example demonstrates the identification of an integer data type called x, which is later displayed using the print method of the f function:

x = 100
def f():
    print(x)
f()
print(x)

100
100

As can be seen from the results of program execution, the value 100 is reproduced not only through f, but also through the usual print. Thus x can be accessed from any part of the code, because of the global scope of such an object. But what happens if we try to change the value of a global variable in a function? The results of this experiment are shown in the following code snippet:

x = 100
def f():
    x = 200
f()
print(x)

100

The function f assigns the value 200 to a variable named x, but, contrary to expectations, the external method print outputs the number 100, which originally belonged to x. This is because this program creates two different x’s with a local scope as well as a global scope. The global keyword can fix this:

x = 100
def f():
    global x
    x = 200
f()
print(x)

200

By marking the variable x as global, we can refer to its original value, which was defined outside the scope of the function f. Now, after putting the number 200 in x, a call to the print method outputs the expected result, which is the changed value.

In Python, global variables can be used to store some settings for a program or module under development. Dictionaries are good for this.

But do not overuse them. Often it is much more correct to pass necessary values as arguments to functions, and if you want to overwrite a global value, return it from the function.

def my_abs(val):
    return -val if val < 0 else val
    return val + 1
x = -15
x = my_abs(x)

Non-local variables

So, to access a global variable within function f, we need to use the keyword global before its identifier. But what if you want to call a variable that isn’t global at all but is defined in a method externally that is local to another namespace layer above it? The following code shows an attempt to manipulate a value from the external function f1 in method f2

def f1():
    x = 100
    def f2():
        x = 200
    f2()
    print(x)
f1()

100

Although a new value of 200 has been assigned to the variable with the same name x, the written methods result in the display of 100. As in the case of the two different variables, local and global, there are also two different objects here that are identified in separate blocks of code. To refer to an object that is not local, you must use the nonlocal modifier:

def f1():
    x = 100
    def f2():
        nonlocal x
        x = 200
    f2()
    print(x)
f1()

200

Thus, in method f2 the value 200 is written to variable x from function f1. As a result, calling method f1 from the external part of the program creates a new variable x, the value of which is changed in f2 from 100 to 200 and outputted with print.

It is important to note that the nonlocal construct was added only in version 3 of the Python language.

Visibility from a loadable module

Now let’s deal with the visibility of global variables between Python modules that we load. For example, we plug in another module using the import command. Let’s create the file “test.py” and put the following code in it:

print('The test module is being loaded')
x = 100
def f():
    print('From function x=' + str(x))

So we defined global variable x for module test. Also, we have defined a function that displays its value. Now we create the file main.py to run it. In it, we import the test module, and create our own global variable x. Then print the global variable’s value from test, call the function f, and make sure it hasn’t changed in main:

x = 200
print('From the module main x=' + str(x))
import test
print('From the module test x=' + str(test.x))
print('Assign value 300')
test.x = 300;
print('From the module test x=' + str(test.x))
test.f()
print('From module main x=' + str(x))

From the main module x=200
The test module is loaded
From the module test x=100
Assign value 300
From the module test x=300
From the function x=300
From the module main x=200

In the first line we have written in x the value 200. This was done to show that after we load the external module, the value of this variable will not change. And so it did. By accessing the variable from the loaded library, we were able to read it and change its value. Now modify the program as follows:

x = 200
print('From main module x=' + str(x))
from test import *
f()
print('From the module main x=' + str(x))
print('Assign value 300')
x = 300
f()
print('From the module main x=' + str(x))

From the main module x=200
The test module is loaded
From the function x=100
From the module main x=100
Assign value 300
From the function x=100
From the module main x=300

In this case we used the command “from test import *” to load. We imported all variables and functions. After loading the module the value of the variable x in the main module changed. But when we call the function, we get the value of x from the test module. After we assign a new value to x variable, the value displayed by f function does not change.

It is necessary, if possible, to avoid connecting libraries using the command from library import *

, and connect only necessary functions – from library import function. Make sure that these names are not used in the main module.

Using the import library

will help to avoid possible errors if the program contains functions, classes and variables with the same names as in the loaded module.

Global variables in a class

Just like in functions, you can refer to global variables in a Python class as well. Let’s break down an example:

x = 100
print(x)
class c1:
    global x
    x = 200
    def __init__(self):
        global x
        x = 300
    def f(self):
        global x
        x = 400
print(x)
o1 = c1()
print(x)
o1.f()
print(x)

100
200
300
400

We declared a global variable x. Displayed the value of the variable before and after the class is declared. As you can see the value has changed. After we created the object of the class, the value changed again. This happened because the class constructor triggered the __init__ method. After calling the function f on the created object, the value became 400. In Python, using global variable both in the class function and in its constructor and after the class description gives you the ability to change the global variable. If you remove this declaration, then the local variable will be assigned. Of course, if we define a local variable in a class, it cannot be accessed from another class:

class c1:
    x = 100
class c2:
    def f(self):
        print(x)
o = c2()
o.f()

Traceback (most recent call last):
File “main.py”, line 7, in <module&gt
o.f()
File “main.py”, line 5, in f
print(x)
NameError: name ‘x’ is not defined
For the code to work, the x variable must be global.

Conclusion

So the scope of variables in the Python programming language is an important part of the platform. Proper interaction with all of its features avoids a lot of rather complex errors. The keywords global and nonlocal are used for safer control over the visibility of individual objects. To learn more about this topic, you should study PEP 3104.

   

Related Posts

LEAVE A COMMENT