Global and local scoping of variables
A variable is a label for a location in memory. It can be used to hold a value. In statically typed languages like C#, variables have predetermined types, and a variable can only be used to hold values of that type. In Python, just like Bash, we may reuse the same variable to store values of any type. A variable is similar to the memory functionality found in most calculators, in that it holds one value which can be retrieved many times, and that storing a new value erases the old. A variable differs from a calculator's memory in that one can have many variables storing different values, and that each variable is referred to by name.
To define a new variable in Python, we simply assign a value to a label. This is exactly the same syntax as assigning a new value to an existing variable called count. If we try to access the value of a variable which hasn't been defined anywhere yet, the interpreter will exit with a name error.
Not all variables are accessible from all parts of our program, and not all variables exist for the same amount of time. Where a variable is accessible and how long it exists depend on how it is defined. We call the part of a program where a variable is accessible its scope, and the duration for which the variable exists its lifetime.
Declaring variables
foo = "Hello World"
Assigning varialbes
foo = "John Doe"
In Python, we declare a variable by assigning a variable name to a value
Global variables
A variable that is defined in the main body of a file is called a global variable. It will be visible throughout the file, and also inside any file which imports that file. Global variables may have unintended consequences because of their wide-ranging effects. Only objects which are intended to be used globally, like functions and classes, should be put in the global namespace.
1 a = 0 2 if a == 0: 3 b = 1 4 c = 3 5 print (d)
Lines 1, 3 and 4 all declare global variables. Also note that line 5 doesn't produce an error and outputs nothing to the screen
Local variables
A variable which is defined inside a function is local to that function. It is accessible from the point at which it is defined until the end of the function, and exists for as long as the function is executing. The parameter names in the function definition behave like local variables, but they contain the values that we pass into the function when we call it. When we use the assignment operator, "= inside a function, its default behavior is to create a new local variable, unless a variable with the same name is already defined in the local scope.
1 a = "Hello " 2 myFunc() 3 print (a) 4 print (b) 5 def myFunc(): 6 print (a) 7 b = " World" 8 print (b)
Line 1 declares the global variable, a and line 7 declares the variable local to "myFunc( )." Line 4 will not produce an error and will output nothing since s is outside the scope of myFunc() similar to the way Bash handles local scope. The output will be the following:
    Hello World
Crossing boundaries
It is possible to access global variables from inside a function but there are some tripping points. If we want to modify a global variable from inside a function?, we can use the global keyword. We may not refer to both a global variable and a local variable by the same name inside the same function.
1 a = "Hello World" 2 def myFunc(): 3 print(a) 4 my_function()
The above code will output Hello World as expected
1 a = "Hello World" 2 def myFunc(): 3 a = "John Doe" 4 print(a) 5 my_function() 6 print(a)
The print statement in line 4 will output John Doe but the print statement in line 6 will output Hello world. This is because line 3 declares a new local variable, "a," which is different from the global variable declaration on line 1.
1 a = "Hello World" 2 def myFunc(): 3 global a 4 a = "John Doe" 5 print(a) 6 my_function() 7 print(a)
In the above code, both print statements on lines 5 and 7 output John Doe. This is the proper way to change global variables if we choose to do so
Class variables scoping
The inside of a class body is also a new local variable scope. Variables which are defined in the class body but outside any class method are called class attributes. They can be referenced by their bare names within the same scope, but they can also be accessed from outside this scope if we use the attribute access operator "." on a class or an instance of an object which uses that class as its type. An attribute can also be set explicitly on an instance or class from inside a method. Attributes set on instances are called instance attributes. Class attributes are shared between all instances of a class, but each instance has its own separate instance attributes. In C#, class instance variables are declared using the "static" keyword and instance attributes are declared using the "public" keyword.
1 class MyClass(object): 2 class_attrib = 1 3 4 def __init__(self, i_var): 5 self.instance_var = "foo"