Introduction This section will provide a short introduction to
namespaces in Scorpion and Python. These concepts are important for
everybody who wants to exploit the power of Python in Scorpion.
Variables and namespaces
All variables in Python, and every other programming language, are created
and exist in a namespace. What is a namespace?
Using PythonWin, an integral part for Python Extension for Windows, or
Idle - yet another Python environment, one can play with namespaces.
An assignment is a statement of type a=b where a is a variable and
b another variable,
constant, constructor or function.
a=100
b=1.03
c=’spam’
e=[]
f={}
g=eggs()
are assignments where
- a is assigned an integer value,
- b a floating point value,
- c a string
- e an empty list
- f an empty dictionary
- g the value of function or a reference to an instance of a class
When Python is initialized, a namespace is created. It is available for
declaration of variables, functions and objects.
Declarations
a=100
def foo(b):
print ‘a=’,a,’b=’,b
The statement
foo(200)
Will yield the output
a=100 b=200
Python searches for a local definition of a in foo(). If not found
Python search in the global namespace. If a local variable is defined in
foo() the result will be as follows:
Declarations
a=100
def foo(b):
a=300
print ‘a=’,a,’b=’,b
The statement
foo(200)
Will yield the output
a=300 b=200
The statement
print ‘a=’,a
Will yield the output
a=100
Functions and name spaces can be nested
a=100
def foo(b):
a=300
def spam(b):
a=400
print ‘a=’,a,’b=’,b
spam(500)
print ‘a=’,a,’b=’,b
The statement
foo(200)
Will yield the output
a=400 b=500
a=300 200
The statement
print ‘a=’,a
Will yield the output
a=100
Lets modify this slightly:
a=100
def foo(b):
def spam(b):
print ‘a=’,a,’b=’,b
spam(500)
print ‘a=’,a,’b=’,b
The statement
foo(200)
Will yield the output
a=100 b=500
a=100 b=200
The statement
print ‘a=’,a
Will yield the output
a=100
Python finds the value of a by searching in the nested namespaces. To change a global variable we can instruct Python to do so.
a=100
def foo(b):
def spam(b):
global a
a=b
print ‘a=’,a,’b=’,b
spam(500)
print ‘a=’,a,’b=’,b
The statement
foo(200)
Will yield the output
a=500 b=500
a=500 200
The statement
print ‘a=’,a
Will yield the output
a=500
A Script - An ordered collection of statements
A script is an ordered collection of Python statements.
Scripts are stored
in a text format. This can be a file. The file is given the .py extension
and is called a module. It can also be named a Script. To get access
to the variable, classes and functions we use the import directive.
When loading the module all definitions and assignments are executed.
Functions, classes and variables must be imported to get into scope.
The
module cannot access methods and functions defined outside the module
unless the import statement is used.
How do we access the content of a module?
We create a module named OneModule.py with content
a='One Module'
z='Another Module'
def foo(c):
print 'What happens next?'
Lets store the module in the directory c:\PythonPrimer.
This is a
directory Pyhton does not know. It can be added to the Python system path with
the following statements:
import sys
sys.path.append(’c:\\pythonprimer’)
sys is a standard module in Python. path is a property in the sys module.
More information about sys and path is found in the Python Help file.
Qualified Import
import OneModule
a = 100
print a
100
print OneModule.a
’OneModule’
We see that the two a variable are in different name spaces. We get
access to OneModule.a using dot notation.
Unqualified Import
What happens if we import OneModule using the import * syntax?
from OneModul import *
print a
’One Module’
The global variable a is assigned by the OneModule script. Calling foo()
will show that foo() is redefined or destroyed?
foo(100)
’What happens next?’
Unqualified import can be dangerous - it will redefine functions
and possibly overwrite variables when names are identical.
Hint : Use qualified import to avoid accidents
Classes have their own namespaces
A way to protect your functions and variables is to use a class to
create a protected name space. Another benefit is that one can create
multiple instances of the class - which is a powerful feature making life
easier and more fun for a lazy programmer (lazy programmers =
efficient programmers).
We create another module AnotherModule.py. Then define a class named
ASimpleClass and store it in C:\PythonPrimer
class ASimpleClass:
def __init__(self):
self.a=’A Simple Class’
def foo(self,b):
print ‘a=’,self.a,‘b=’,b
Statements and output
from AnotherModule import *
m=ASimpleClass()
print m. a
’A Simple Class’
m.foo(’spam’’)
a=’A Simple Class’ b=’spam’
m.a=a
print m.a
a=100
You can protect variables using a class definition this way:
class Glob:
a=100
glob=Glob()
print glob.a
100
glob.b=200
print glob.b
200
As you can see you can add new variables to the class - on the fly! -
and get the protection and scoping you need.
Python and Scorpion
Python is integrated in Scorpion. You may write Python code in:
- PythonTools
- Central
Central.Start
Central.Stop
Central.Scripts
Central.Start is the starting
point for all Python execution within Scorpion. Central.Start is run
by Scorpion during
startup which means that this is THE place to put global declarations of
classes, functions and variables. Anything
declared within Central.Start is available to PythonTools and
Central.Scripts.
Good programming practice in
Scorpion:
-
Declare all variables,
functions and classes that are ment to be global in Central.Start
-
Use the global
directive in all scripts referring to global variables, even though if
the variables
are only ReadOnly. Tell yourself and any other user of your
profile that you know exactly what you are doing.
-
Any variable declared in a
PythonTool should be regarded as local to this script. They will
become global after
the first assignment - but this is bad practice.
-
Do not import your own
modules with the from module import * statement if the module contains
global assignments.
The consequence is that previous declared global vaiables with equal
names will be overwritten. Use the import statement instead.
-
Try rewriting modules
containing variables and functions into classes.
|