X = 99

def func():
    X = 88



# Global scope
X = 99                # X and func assigned in module: global
          
def func(Y):          # Y and Z assigned in function: locals
    # local scope
    Z = X + Y         # X is a global.
    return Z

func(1)               # func in module: result=100



>>> import __builtin__
>>> dir(__builtin__)
['ArithmeticError', 'AssertionError', 'AttributeError', 'DeprecationWarning', 
'EOFError', 'Ellipsis', 
    ...many more names ommitted...
'str', 'super', 'tuple', 'type', 'unichr', 'unicode', 
'vars', 'xrange', 'zip']



>>> zip                        # The normal way
<built-in function zip>

>>> import __builtin__         # The hard way
>>> __builtin__.zip
<built-in function zip>



def hider():
    open = 'spam'        # Local variable, hides built-in
    ...
    open('data.txt')     # This won't open a file now in this scope!



X = 88          # Global X

def func():
    X = 99      # Local X: hides global

func()
print X         # Prints 88: unchanged



X = 88          # Global X

def func():
    global X
    X = 99      # Global X: outside def

func()
print X         # Prints 99



y, z = 1, 2         # Global variables in module

def all_global():
    global x        # Declare globals assigned.
    x = y + z       # No need to declare y,z: LEGB rule



X = 99

def func1():
    global X
    X = 88

def func2():
    global X 
    X = 77



# first.py
X = 99

# second.py
import first
first.X = 88



# first.py
X = 99

def setX(new):
    global X
    X = new

# second.py
import first
first.setX(88)



# File: thismod.py

var = 99                    # global variable == module attribute

def local():
    var = 0                 # change local var
    
def glob1():
    global var              # declare global (normal)
    var += 1                # change global var

def glob2():
    var = 0                 # change local var
    import thismod          # import myself
    thismod.var += 1        # change global var

def glob3():
    var = 0                           # change local var
    import sys                        # import system table
    glob = sys.modules['thismod']     # get module object (or use __name__)
    glob.var += 1                     # change global var

def test():
    print var
    local(); glob1(); glob2(); glob3()
    print var



    
>>>  import thismod
>>>  thismod.test()
99
102
>>>  thismod.var
102



def f1():
    x = 88
    def f2():
        print x
    f2()

f1()                  # Prints 88



def f1():
    x = 88
    def f2():
        print x
    return f2

action = f1()            # Make, return function.
action()                 # Call it now: prints 88



>>> def maker(N):
        def action(X):
            return X ** N
    return action



>>> f = maker(2)                            # pass 2 to N
>>> f
<function action at 0x014720B0>

>>> f(3)                                    # pass 3 to X, N remembers 2
9
>>> f(4)                                    # 4 ** 2
16

>>> g = maker(3)
>>> g(3)                                    # 3 ** 3
27
>>> f(3)                                    # 3 ** 2
9



def f1():
    x = 88
    def f2(x=x):
        print x
    f2()

f1()                  # Prints 88



>>> def f1():
...     x = 88
...     f2(x)
...
>>> def f2(x):
...     print x
...
>>> f1()
88



def func():
    x = 4
    action = (lambda n: x ** n)          # x remembered from enclosing def
    return action

x = func()
print x(2)                               # Prints 16, 4 ** 2



def func():
    x = 4
    action = (lambda n, x=x: x ** n)     # Pass x in manually.



>>> def makeActions():
        acts = []
        for i in range(5):                          # tries to remember each i
            acts.append(lambda x: i ** x)           # all remember same last i!
        return acts

>>> acts = makeActions()
>>> acts[0]
<function <lambda> at 0x012B16B0>

>>> acts[0](2)                             # all are 4 ** 2, value of last i
16
>>> acts[2](2)                             # this should be 2 ** 2  
16
>>> acts[4](2)                             # this should be 4 ** 2
16



>>> def makeActions():
        acts = []
        for i in range(5):                               # use defaults instead
            acts.append(lambda x, i=i: i ** x)           # remember current i
    return acts

>>> acts = makeActions()
>>> acts[0](2)                        # 0 ** 2
0
>>> acts[2](2)                        # 2 ** 2
4
>>> acts[4](2)                        # 4 ** 2
16



>>> def f1():
...     x = 99
...     def f2():
...         def f3():
...             print x       # Found in f1's local scope!
...         f3()
...     f2()
...
>>> f1()
99



>>> def changer(a, b):     # Function
...    a = 2               # Changes local name's value only
...    b[0] = 'spam'       # Changes shared object in place
...
>>> X = 1
>>> L = [1, 2]             # Caller
>>> changer(X, L)          # Pass immutable and mutable
>>> X, L                   # X unchanged, L is different
(1, ['spam', 2])



>>> X = 1
>>> a = X           # they share the same object
>>> a = 2           # resets a only, X is still 1
>>> print X
1

>>> L = [1, 2]
>>> b = L           # they share the same object
>>> b[0] = 'spam'   # in-place change: L sees the change too
>>> print L
['spam', 2]



L = [1, 2]
changer(X, L[:])       # Pass a copy, so my L does not change.



def changer(a, b):
   b = b[:]            # Copy input list so I don't impact caller.
   a = 2
   b[0] = 'spam'       # Changes my list copy only



L = [1, 2]
changer(X, tuple(L))   # Pass a tuple, so changes are errors.



>>> def multiple(x, y):
...     x = 2                    # Changes local names only
...     y = [3, 4]
...     return x, y              # Return new values in a tuple.
...
>>> X = 1
>>> L = [1, 2]
>>> X, L = multiple(X, L)        # Assign results to caller's names.
>>> X, L
(2, [3, 4])




>>> def f(a, b, c): print a, b, c
...

>>> f(1, 2, 3)
1 2 3

>>> f(c=3, b=2, a=1)
1 2 3

>>> f(1, c=3, b=2)
1 2 3

func(name='Bob', age=40, job='dev')



>>> def f(a, b=2, c=3): print a, b, c
...

>>> f(1)
1 2 3
>>> f(a=1)
1 2 3

>>> f(1, 4)
1 4 3
>>> f(1, 4, 5)
1 4 5

>>> f(1, c=6)
1 2 6



>>> def f(*args): print args

>>> f()
()
>>> f(1)
(1,)
>>> f(1,2,3,4)
(1, 2, 3, 4)



>>> def f(**args): print args
...
>>> f()
{  }
>>> f(a=1, b=2)
{'a': 1, 'b': 2}



>>> def f(a, *pargs, **kargs): print a, pargs, kargs
...
>>> f(1, 2, 3, x=1, y=2)
1 (2, 3) {'y': 2, 'x': 1}



>>> def func(a, b, c, d): print a, b, c, d

>>> args = (1, 2)
>>> args += (3, 4)
>>> func(*args)
1 2 3 4



>>> args = {'a': 1, 'b': 2, 'c': 3}
>>> args['d'] = 4
>>> func(**args)
1 2 3 4



>>> func(*(1, 2), **{'d': 4, 'c': 4})
1 2 4 4

>>> func(1, *(2, 3), **{'d': 4})
1 2 3 4

>>> func(1, c=3, *(2,), **{'d': 4})
1 2 3 4



def func(spam, eggs, toast=0, ham=0):   # First 2 required
    print (spam, eggs, toast, ham)

func(1, 2)                              # Output: (1, 2, 0, 0)
func(1, ham=1, eggs=0)                  # Output: (1, 0, 0, 1)
func(spam=1, eggs=0)                    # Output: (1, 0, 0, 0)
func(toast=1, eggs=2, spam=3)           # Output: (3, 2, 1, 0)
func(1, 2, 3, 4)                        # Output: (1, 2, 3, 4)



# mins.py

def min1(*args):
    res = args[0]
    for arg in args[1:]:
        if arg < res:
            res = arg
    return res

def min2(first, *rest):
    for arg in rest:
        if arg < first:
            first = arg
    return first

def min3(*args):
    tmp = list(args)              # or in Python 2.4+: return sorted(args)[0]
    tmp.sort()
    return tmp[0]

print min1(3,4,1,2)
print min2("bb", "aa")
print min3([2,2], [1,1], [3,3])



% python mins.py
1
aa
[1, 1]



def minmax(test, *args):
    res = args[0]
    for arg in args[1:]:
        if test(arg, res):
            res = arg
    return res

def lessthan(x, y): return x < y                # see also: lambda
def grtrthan(x, y): return x > y

print minmax(lessthan, 4, 2, 1, 5, 6, 3)        # self-test code
print minmax(grtrthan, 4, 2, 1, 5, 6, 3)

% python minmax.py
1
6



# inter2.py

def intersect(*args):
    res = []
    for x in args[0]:                  # Scan first sequence
        for other in args[1:]:         # for all other args.
            if x not in other: break   # Item in each one?
        else:                          # No:  break out of loop
            res.append(x)              # Yes: add items to end
    return res

def union(*args):
    res = []
    for seq in args:                   # For all args
        for x in seq:                  # For all nodes
            if not x in res:
                res.append(x)          # Add new items to result.
    return res



% python
>>> from inter2 import intersect, union
>>> s1, s2, s3 = "SPAM", "SCAM", "SLAM"

>>> intersect(s1, s2), union(s1, s2)           # Two operands
(['S', 'A', 'M'], ['S', 'P', 'A', 'M', 'C'])

>>> intersect([1,2,3], (1,4))                  # Mixed types 
[1]

>>> intersect(s1, s2, s3)                      # Three operands
['S', 'A', 'M']

>>> union(s1, s2, s3)
['S', 'P', 'A', 'M', 'C', 'L']



from Tkinter import *
widget = Button(text="Press me", command=someFunction)



>>> X = 'Spam'
>>> def func():
        print X
	
>>> func()



>>> X = 'Spam'
>>> def func():
        X = 'NI!'
	
>>> func()
>>> print X



>>> X = 'Spam'
>>> def func():
        X = 'NI'
        print X
	
>>> func()
>>> print X



>>> X = 'Spam'
>>> def func():
        global X
        X = 'NI'
	
>>> func()
>>> print X



>>> X = 'Spam'
>>> def func():
        X = 'NI'
        def nested():
            print X
        nested()
	
>>> func()
>>> X



>>> def func(a, b, c=3, d=4): print a, b, c, d
	
>>> func(1, *(5,6))

