Scope rule in the function of python & LGB Rule
function of python
One of the fundamentals of any programming language is that there are often repeated elements in your programs. You can cut and paste code from one particular part of the program. You’d have to modify each duplicated section individually. For very small programs this is unlikely to generate any significant overhead, but as the size and complexity of the program increases, so does the time required to modify and update essentially the same piece of code over and over.
Duplication also runs the risk of introducing additional syntactic, logical, and typographical errors Imagine duplicating a sequence that contained a simple typing mistake-you would have to trace every single instance to isolate the problem! This is where functions solve all your problems. By placing the repeated code into a function you isolate that code sequence and provide easier access to improve the code or isolate bugs.
This method of taking repeated pieces of code and placing them into a function is called abstraction. In general, a certain level of abstraction is always useful-it speeds up the programming process, reduces the risk of introducing errors, and makes an l complex program easier to maintain. For the space-conscious programmer, using functions also reduces the number of lines in your code and the overall memory footprint of the program during execution.
You already know that Python has three basic levels of abstraction
1. A program can be split into multiple modules.
2. Each module contains multiple statements.
3. Each statement operates on objects.
Functions sit around stage 2-they provide a way of collating repeated sequences of statements into one place.
Python also provides one of the best systems for code reuse. Once you have written a Python function, it is immediately available to any other program just by importing the function from the source file. There is no need to create a special library and header file, as you need to in C/C++, nor do you need to create a special “module” as you do in Perl. With Python, code reuse is as simple as knowing which file the function is stored in.
Beyond the normal features offered by other languages for implementing functions. Python allows a greater level of control and integration over the arguments that you supply to the function and how they are treated. You also have complete flexibility over the values you return to the caller-you are not restricted as you are with C or C++ to a specific data type.
With Python, functions form the basis of methods, the functions that operate and perform specific actions on objects and object classes. The creation of object classes and the use of modules for code reuse are covered in Chapters 5 and 6. For the moment. we’ll concentrate on the basic mechanics of functions and how they can be employed within a single Python module file.
Function Definition and Execution
The general format for creating a new function is as follows:
def NAME(ARGI [, ...]): STATEMENT BLOCK [return VALUE]
The NAME should follow the same rules as object names:
•Functions must begin with an underscore or letter and may contain any combination of letters, digits, or underscores. You cannot use any other punctuation characters.
•Functions are case sensitive combine and Combine are two different function names. However, you should avoid creating functions of the same name but in different cases.
•You cannot use a reserved word for a function name, but remember the case-sensitive rule above.
When you define the function, you must include the parentheses, even if you are not accepting any arguments to the function. If you are accepting arguments to the function, the arguments must be named within the parentheses, although the way they are named is slightly different from other languages. We’ll look at the specifics of the argument passing shortly.
As with control statements, the statement block for the function must be preceded by a colon. The closing return statement is optional; if you don’t use it, the function returns to the caller without returning a value A Python function without a return statement always returns the special value None.
The following example is a simple function that calculates the area of a circle based on the radius supplied:
Note:- The value of a given in the preceding example is an approximation. A better value can be found in the Python math library as pi.
To use the area function, just call it with an argument:
print area (2)
which returns 12.564. Note the precision in the result is identical to the precision you use for the value of #. If you supply a value with higher decimal precision, the return value is also of higher precision. The statement
which returns 31.0004274319.
which returns 31.0004274319.
When calling a function, make sure that you include the parentheses, Python does not allow function calls of the form
This is a common error of Perl programmers who often leave out the parentheses to make a program more readable. This is further complicated by the fact that print is a statement rather than a function, so you can call print without using parentheses. If you do use parentheses, print outputs a tuple!
Finally, unlike other languages, functions within Python can be defined on the fly_you can create a function anywhere within the normal execution of a program.
The following code is perfectly valid:
If (message): Def function (): Print "Hello!\n"; else: def function (): print "Goodbye!\n";
and opens up all sorts of possibilities, especially when it comes to the development of objects and methods.
The scoping, argument definition, return values, and methods for calling functions all have extended feature sets within the Python language so let’s look at each feature individually.
Python uses the concept of names in order to store information about objects and their location within an application. Namespaces are specific to a particular level of abstraction there are individual namespaces for functions and modules, and there’s a special namespace for the built-in functions, statements, and objects. At each level. when you access an object or function, Python searches the namespace tables looking for the specified name so it can look up the reference and decide what to do with the information stored at that location. Scoping within Python follows these basic rules:
1. Each module has its own scope. This means that multiple modules have their own scope, and therefore their own namespaces: Chapter 5 discusses this in more detail.
2. The enclosing module for a function is called the global scope. This is the location of objects created at the top level of a module file.
3. New function definitions create new scopes; the scopes are unique to the function.
4. New objects are assigned to the local scope unless declared otherwise. Any variable or function that is defined will be a member of the local scope unless you declare it global with the global keyword.
5. Arguments to a function are defined within the local function scope.
The scoping rules mean that objects created within a function do not interfere with identically named objects in the module (global) or built-in namespaces. Our area function is a good example:
def area(radius): area = 3.141*(pow(radius,2)) return area
The area function is global because it’s defined within the top level of the module The area variable is defined within the local scope of the area function. This means that although they have the same name, they do not interfere with each other. If you want to create a recursive function, you obviously have to use a different name for the variable, since Python would see the area variable before it identified the function and would therefore raise an exception. (See Chapter 7 for a detailed discussion of exceptions.)
Making Objects Global
There are occasions when you want to assign the value of a variable within a function. but t you have it modify the global variable instead of creating a new one. The traditional method for this is to predeclare the variable before the function is called:
name = 'unknown' def set_defaults(): Name = 'Martin' Set_defaluts() Print name
However, in Python this doesn’t work because the moment you assign the name variable within the function, Python creates a new variable within the local scope. To get around this, you need to use the global keyword to define which variables you want to use in this way. The global keyword tells Python to create a local alias for the global variable. For example, if you modify the preceding script:
name = 'unknown' def set_default(): global name name = 'Martin' set_defaults() prints name
This function does what you expect; it prints the name “Martin.”
The global keyword also creates objects within the global namespace if they don’t already exist, as in the following example:
def set_defaults(): global name, address name = 'Martin' address = 'firstname.lastname@example.org' Set_defaults() print "Name" ,name, "Address" ,address
The preceding fragment, when executed, produces
Name: martin Address: email@example.com
The LGB Rule
The LGB rule is a simple way of remembering how Python looks up names within the scope of
•Name references search the three scopes in order local, then global, then built-in (LGB).
•Name assignments to create new objects or update objects in the local scope. Thus if you want to assign to global objects within a local scope, you must use the global keyword.
•Global declarations map assigned names to the scope of the enclosing module. This means you must either explicitly import objects from imported modules or use the fully qualified module/object name.
The last entry in this list will not make sense until you learn about the mechanics of modules in Chapter 5, but be aware that so-called global definitions are only global to the current module.
Consider the following code fragment:
radius = 2 pi- 3.141592654 def area(radius): area = pi *(pow(radius, 2)) return area print area(4)
In this example, you’ve defined two global variables, radius, and pi. The area function looks for the name radius when it is executed and finds it locally, ignoring the global variable. The pi variable cannot be found locally, so Python looks globally and finds the variable there.
You can see a layout more clearly in Figure 4-1.
Caution:-The more observant reader will have noticed that the LGB rule also means that local variables can override global variables and that both local and global variables can override the built-in variables. For example, a local variable can be called open, but using this would make it impossible to call the function open within the same scope unless it was explicitly identified. It’s therefore a bad idea to use locals with the same name as globals or built-ins.
There is one significant trap that catches many people off guard. The name-resolving process only searches the three abstraction layers local, global, and built-in (see the earlier section The LGB Rule”). It’s possible in Python to define functions within other functions. This can often be useful when you want to create a group of functions that are not publicly available to the outside world. The problem is that the scoping rules still apply. Consider the following example:
def funca(): value = 59 Funch() det funcb(): print (value *2)
The preceding code will fail because funcb is trying to access the variable value. However, value does not exist within either the local, global, or built-in scope-and it fails the LGB rule. Functions do not automatically inherit the scope of the parent, nor does the Python namespace manager search the parent scope of a function.
The way to get around this is to make value an argument to the embedded function:
der funca(): value =59 funcb() def funcb(value): print (value*2)
You can use the same name because value will still be local to the funcb scope and so it still works with the LBC rule.