0% found this document useful (0 votes)
68 views25 pages

Lecture 7

This document discusses variable scope in Python. Some key points: - Variables introduced inside functions have local scope, while variables outside have global scope. The global keyword can modify a global variable from within a function. - Mutable objects like lists passed to functions can be modified in-place, but rebinding the variable only changes the local reference. - Nested functions follow LEGB scoping rules (Local, Enclosing, Global, Built-in). The nonlocal keyword can modify an enclosing scope variable. - Functions can accept arbitrary positional (*args) and keyword (**kwargs) arguments to handle flexible numbers of arguments. Mixing positional and kwargs requires kwargs at the end.

Uploaded by

hj lin
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
68 views25 pages

Lecture 7

This document discusses variable scope in Python. Some key points: - Variables introduced inside functions have local scope, while variables outside have global scope. The global keyword can modify a global variable from within a function. - Mutable objects like lists passed to functions can be modified in-place, but rebinding the variable only changes the local reference. - Nested functions follow LEGB scoping rules (Local, Enclosing, Global, Built-in). The nonlocal keyword can modify an enclosing scope variable. - Functions can accept arbitrary positional (*args) and keyword (**kwargs) arguments to handle flexible numbers of arguments. Mixing positional and kwargs requires kwargs at the end.

Uploaded by

hj lin
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 25

Python Programming

Lecture 7 Variable Scope, Arbitrary Arguments


7.1 Variable Scope
Variable Scope ( 变量的作用域)
In Python, module, class, def, lambda can introduce new variable scope, if/elif/else/, try/except, for/while
will not introduce new variable scope.

1 if True:
2 msg = 'I am from Shanghai'
3 print(msg) # We can use msg.

1 def test():
2 msg = 'I am from Shanghai'
3 print(msg) # error

Global and Local

1 msg_loc = "Shanghai" # Global


2 def test():
3 msg = 'I am from Shanghai' # Local
New Assignment

1 msg = 'I am from Shanghai'


2 def test(): I am from Beijing
3 msg = 'I am from Beijing' I am from Shanghai
4 print(msg)
5 test()
6 print(msg)

Reference

1 msg = 'I am from Shanghai'


2 def test(): I am from Shanghai
3 print(msg)
4 test()

Modification

1 msg = 'I am from Shanghai'


2 def test(): UnboundLocalError: local variable 'msg'
3 print(msg) referenced before assignment
4 msg = 'I am from Beijing'
5 test()
How to modify the variable outside? The global keyword

1 num = 1
2 def fun(): 123
3 global num 123
4 num = 123
5 print(num)
6 fun()
7 print(num)

1 num = 1
2 def fun(): SyntaxError: name 'num' is used
3 print(num) prior to global declaration
4 global num
5 num = 123
6 print(num)
7 fun()
1 a = 10
2 def test(): UnboundLocalError: local variable 'a'
3 a = a + 1 referenced before assignment
4 print(a)
5 test()

1 a = 10
2 def test(): 11
3 global a
4 a = a + 1
5 print(a)
6 test()

1 a = 10
2 def test(): 11
3 a = 10 10
4 a = a + 1
5 print(a)
6 test()
7 print(a)
mutable vs. immutable

1 a = [1,2,3]
2 def test(): UnboundLocalError: local variable 'a'
3 print(a) referenced before assignment
4 a = [1,2,3,4]
5 test()

1 a = [1,2,3]
2 def test(): [1, 2, 3]
3 print(a) [1, 2, 3, 4]
4 a.append(4)
5 test()
6 print(a)

1 a = {"color": "green"}
2 def test(): {'color': 'green'}
3 print(a) {'color': 'red', 'position': 'left'}
4 a["color"] = "red"
5 a["position"] = "left"
6 test()
7 print(a)
Parameter and Argument

For immutable objects (number, string, tuple), the assignment inside a function cannot change the value
of the variable outside the function even if the variable name inside is the same with the variable name
outside.

1 def ChangeInt(a):
2 a = 10 10
3 return a 2
4
5 b = 2
6 print(ChangeInt(b))
7 print(b)

1 def ChangeInt(b):
2 b = 10 10 2
3 return b
4
5 b = 2
6 x = ChangeInt(b)
7 print(x, b)
Examples

1 def ChangeInt(a):
2 a = 10 10
3 print(a) 2
4 return a 10
5 10
6 b = 2
7 ChangeInt(b)
8 print(b)
9 print(ChangeInt(b))

1 def ChangeInt(a):
2 a = 10 10
3 print(a) 2
4 10
5 b = 2 None
6 ChangeInt(b)
7 print(b)
8 print(ChangeInt(b))
For mutable objects (list, dictionary), the assignment inside a function cannot change the value of the
variable outside the function. (the same with immutable objects!)

1 def changeme(mylist):
2 mylist = [1,2] inside: [1, 2]
3 print("inside: ", mylist) outside: [10, 20]
4
5 x = [10,20]
6 changeme(x)
7 print("outside: ", x)

However, the modification can change the value of the variable outside.

1 def changeme(mylist):
2 mylist.extend([1,2]) inside: [10, 20, 1, 2]
3 print ("inside: ", mylist) outside: [10, 20, 1, 2]
4
5 x = [10,20]
6 changeme(x)
7 print ("outside: ", x)
7.2 Nested Functions
Nested Functions
1 def outer():
2 def inner():
3 print(100)
4 inner()
5 outer()

1 def outer():
2 def inner():
3 num = 100
4 print(num)
5 inner()
6 outer()

Local→Enclosing→Global→ Build-in (LEGB)

1 num = 3 # Global
2 def outer():
3 num = 10 # Enclosing
4 def inner():
5 num = 100 # Local
6 print(num)
7 inner()
8 print(num)
9 outer()
The nonlocal keyword

1 def outer():
2 num = 10 100
3 def inner(): 100
4 nonlocal num
5 # nonlocal keyword
6 num = 100
7 print(num)
8 inner()
9 print(num)
10 outer()

1 def outer():
2 num = 10 100
3 def inner(): 10
4 global num
5 # global does not work
6 num = 100
7 print(num)
8 inner()
9 print(num)
10 outer()
1 def outer():
2 global num 100
3 num = 10 100
4 def inner():
5 global num
6 num = 100
7 print(num)
8 inner()
9 print(num)
10 outer()

1 def outer():
2 global num 100
3 num = 10 10
4 def inner():
5 num = 100
6 print(num)
7 inner()
8 print(num)
9 outer()
1 num = 3
2 def outer(): 100
3 global num 10
4 num = 10 10
5 def inner():
6 num = 100
7 print(num)
8 inner()
9 print(num)
10 outer()
11 print(num)

1 num = 3
2 def outer(): 100
3 num = 10 10
4 def inner(): 100
5 global num
6 num = 100
7 print(num)
8 inner()
9 print(num)
10 outer()
11 print(num)
1 num = 3
2 def outer(): 100
3 num = 10 100
4 def inner(): 3
5 nonlocal num
6 num = 100
7 print(num)
8 inner()
9 print(num)
10 outer()
11 print(num)

1 num = 3
2 def outer(): 100
3 global num 100
4 num = 10 100
5 def inner():
6 global num
7 num = 100
8 print(num)
9 inner()
10 print(num)
11 outer()
12 print(num)
7.3 Arbitrary Arguments
1 def make_pizza(toppings):
2 print(toppings)
3
4 make_pizza('pepperoni')

If we want to pass multiple arguments, we may create a list at first.

1 x=['mushrooms', 'green peppers', 'extra cheese']


2 def make_pizza(toppings):
3 for y in toppings:
4 print(y, end=', ')
5
6 make_pizza(x)

1 def make_pizza(topping_1, topping_2, topping_3):


2 print(topping_1, topping_2, topping_3)
3
4 make_pizza('mushrooms', 'green peppers', 'extra cheese')

However, sometimes we are not sure about the exact number of the arguments.
We can pass multiple arguments at once in the following way.

1 def make_pizza(*toppings):
2 print(toppings)
3
4 make_pizza('pepperoni')
5 make_pizza('mushrooms', 'green peppers', 'extra cheese')

Note that Python packs the arguments into a tuple, even if the function receives only one value.

1 def make_pizza(*toppings):
2 for topping in toppings:
3 print("- " + topping)
4
5 make_pizza('pepperoni')
6 make_pizza('mushrooms', 'green peppers', 'extra cheese')

- pepperoni
- mushrooms
- green peppers
- extra cheese
Mixing Positional and Arbitrary Arguments

If you want a function to accept several different kinds of arguments, the parameter that accepts an
arbitrary number of arguments must be placed last in the function definition.

1 def make_pizza(size, *toppings):


2 print(str(size) + "-inch pizza:")
3 for topping in toppings:
4 print("- " + topping)
5
6 make_pizza(16, 'pepperoni')
7 make_pizza(12, 'mushrooms', 'green peppers', 'extra cheese')

16-inch pizza:
- pepperoni
12-inch pizza:
- mushrooms
- green peppers
- extra cheese
Using Arbitrary Keyword Arguments

1 def build_profile(**user_info):
2 print(user_info)
3
4 build_profile(location='Shanghai',field='Management')

{'location': 'Shanghai', 'field': 'Management'}

Using Arbitrary Keyword Arguments

1 def build_profile(first, last, **user_info):


2 profile = {}
3 for key, value in user_info.items():
4 profile[key] = value
5 return first, last, profile
6
7 user_profile = build_profile('albert', 'einstein',
8 location='princeton',
9 field='physics')
10 print(user_profile)

('albert', 'einstein',
{'location': 'princeton', 'field': 'physics'})
1 def build_profile(*name, **user_info):
2 print(name)
3 print(user_info)
4
5 build_profile('albert', 'einstein',
6 location='princeton',
7 field='physics')

('albert', 'einstein')
{'location': 'princeton', 'field': 'physics'}

As a tradition, we often use *args and **kw


Example Result

1 def test(x,y=1,*a,**b):
2 print(x,y,a,b)
3
4 test(1) 1 1 () {}
5 test(1,2) 1 2 () {}
6 test(1,2,3) 1 2 (3,) {}
7 test(1,2,3,4) 1 2 (3, 4) {}
8 test(x=1,y=2) 1 2 () {}
9 test(1,a=2) 1 1 () {'a': 2}
10 test(1,2,3,a=4) 1 2 (3,) {'a': 4}
11 test(1,2,3,y=4) TypeError: test() got multiple values
Summary
Functions
Reading: Python for Everybody, Chapter 4
Reading: Python Crash Course, Chapter 8

You might also like