python3基礎10
day10
全域性變數和區域性變數
區域性變數:
定義在函式內部的變數稱為區域性變數(函式的形參也是區域性變數)
區域性變數只能在函式中使用
區域性變數在函式呼叫時才能被建立,在函式呼叫之後會自動銷燬
全域性變數:
定義在函式外部,模組內部的變數稱為全部變數
全域性變數所有的函式都可以直接訪問(但函式內部不能將其賦值)
示例見:
global_local.py
說明:
1.區域性變數只能在其被宣告的函式內部訪問,而全域性變數可以在整個模組範圍內訪問
2.在函式內部賦值語句不會對全域性變數造成影響
3.在區域性範圍內可以訪問全域性變數,但是在全域性不能訪問區域性變數,因為在函式呼叫完畢後,區域性變數銷燬
4.函式名也是全域性變數(fn)
def fn(c, d):
e = 300
示意:
L = []
def input_number():
L2 = []
while True:
n = int(input("請輸入正整數:"))
if n < 0:
break
L2.append(n)
L = L2
input_number()
print(L)
globals()/locals()函式
globals() 返回當前全域性作用域內變數的字典
locals() 返回當前區域性作用域內變數的字典
示例見:
globals_locals.py
a = 1
b = 2
c = 3
def fn(c, d):
e = 300
print("locals()返回",locals())
print("globals()返回",globals())
print(c) #列印區域性變數繫結的物件
print(globals()['3']) #列印全部變數繫結的物件
fn(100, 200)
函式變數:
函式名是變數,它在建立函式時繫結一個函式
示例見:
function_variable.py
def fn():
print("hello world!") #fn繫結函式
f1 = fn #f1也繫結這個函式
print(fn) #<function fn at 0x7f138e4d6f28>
print(f1) #<function f1 at 0x7f138e4d6f28>
print(f1()) #None
def f1():
print("函式f1被呼叫")
def f2():
print("函式f2被呼叫")
f1, f2 = f2, f1 #f1,f2交換繫結
f1() #f2被呼叫
f2() #f1被呼叫
一個函式可以作為另一個函式的實參傳遞
示例見:
function_give_function.py
def f1():
print("hello f1")
def f2():
print("hello f2")
def fx(fn):
print(fn) #<function f1 at 0x7fb921cebf28>
fn() #呼叫fn繫結的函式
fx(f1) #請問如何執行?#fn是函式 fn()是呼叫函式fn
fx(f2)
#fx(f1)就是將f1繫結的語句塊交給fn繫結
看懂下面的程式碼在做什麼:
def myinput(fn):
L = [1,3,5,7,9]
return fn(L)
print(myinput(max)) #9
print(myinput(min)) #1
print(myinput(sum)) #25
函式可以返回另一個函式:
示例見:
return_function.py
def get_function():
s = input("請輸入您要做的操作:")
if s == '求最大':
return max
elif s == '求最小':
return min
elif s == '求和':
return sum
L = [2,4,6,8,10]
f = get_function() #讓get_function返回給我們一個函式
print(f(L))
練習一:
寫一個計算公式的解釋執行器
已知有如下函式:
def myadd(x, y):
return x + y
def mysub(x, y):
return x -y
def mymul(x, y):
return x * y
def get_fun(op):
.....#自己實現
get_fun(op)函式傳入字串'加'或'+'返回myadd
get_fun(op)函式傳入字串'乘'或'*'返回mymul
在主函式中程式如下:
def main():
while True:
s = input("請輸入計算公式:") #10加20
L.s.split() #L = ['10','加','20']
a = int(L[0])
b = int(L[2])
fn = get_fun(L[1])
print("結果是:",fn(a,b)) #結果是:30
#方法一:
def myadd(x, y):
return x + y
def mysub(x, y):
return x - y
def mymul(x, y):
return x * y
def get_fun(op):
if op == '加' or op == '+':
return myadd
if op in ('減', '-'):
return mysub
if op in ('乘', '*'):
return mymul
def main():
while True:
s = input("請輸入計算公式:") #10 加 20
L = s.split() #L = ['10','加','20']
a = int(L[0])
b = int(L[2])
fn = get_fun(L[1])
print("結果是:",fn(a,b)) #結果是:30
main()
#方法二:
def get_fun(op):
if op == '加' or op == '+':
def myadd(x, y):
return x + y
if op in ('減', '-'):
def mysub(x, y):
return x - y
if op in ('乘', '*'):
def mymul(x, y):
return x * y
def main():
while True:
s = input("請輸入計算公式:") #10 加 20
L = s.split() #L = ['10','加','20']
a = int(L[0])
b = int(L[2])
fn = get_fun(L[1])
print("結果是:",fn(a,b)) #結果是:30
main()
函式的巢狀定義:
函式巢狀定義是指一個函式裡用def語句來建立另一個函式的情況
示例:
def fn_outter():
print("fn_outter()被呼叫")
def fn_inner():
print("fn_inner被呼叫")
fn_inner() #呼叫巢狀函式fn_inner
fn_inner() #第二次呼叫
print('fn_outter呼叫結束')
fn_outter() #呼叫外層函式
python3 的四個作用域
作用域也叫名字空間,是訪問變數時查詢變數名的範圍空間
python3 的四個作用域 LEGB
作用域 英文解釋 英文簡寫
區域性作用域(函式內) local(function) L
外部巢狀函式作用域 Enclosing function locals E
函式定義所在模組作用域 Global(module) G
python內建模組的作用域 Builtin(Python) B
注:
內建函式: max min sum 等都在python內建模組的作用域,不能改變,只能讀取
示例見:
namespace.py
v = 100 #函式定義所在模組作用域
def fun1():
v = 200 # 外部巢狀函式作用域
print("fun1.v=",v)
def fun2():
v = 300 #區域性作用域(函式內)
print('fun2.v=',v)
fun2()
fun1()
print("全域性變數v=",v)
變數名查詢規則:
在訪問變數時,先查詢本地(區域性)變數,然後是包裹此函式外部的函式內的變數,之後是全域性變數,最後是內建作用域內的變數
即: L-----> E------> G----->B
在預設情況下,變數名賦值(賦值語句)會在當前作用域內建立變數和修改變數
v = 0
def fn(x):
v += x #錯誤,把v看做區域性變數,在區域性內未繫結
global語句
作用:
告訴解釋執行器,global語句宣告一個或多個變數,這些變數的作用域為模組級作用域,也稱全域性作用域
全域性宣告global將賦值變數對映到模組檔案內部的作用域
語法:
global 變數名1, 變數名2...
示例見:
global.py
v = 100
def fn():
global v # 告訴解釋執行器python3,v是全部變數,不是區域性變數
v = 200
fn()
print('v=',v)
說明:
1.全域性變數如果要在函式內部被賦值,則必須經過全域性宣告(否則
會被認為是區域性變數)
2.全域性變數在函式內部不經過宣告就可以直接訪問
示例: global2.py
v = 100
def fn():
v = 200 # 不建議在globalz之前宣告區域性變數
print(v)
global v #v不能既是全域性又是區域性變數
v = 300
print(v)
fn()
print('v=',v)
3.不能先宣告區域性變數,再用global宣告全域性變數,此做法不和規則
4.global變數列表裡的變數名不能出現在函式的形參列表裡
示例: global3.py
v = 100
def fx(v):
global v #此處錯誤,fx(v)形參中的v與全域性變數中的v衝突
v = 300
fx(v)
print(v)
nonlocal語句
作用:
告訴解釋執行器,nonlocal宣告的變數不是區域性變數,也不是全域性變數,而是外部巢狀函式內的變數
語法:
nonlocal 變數名1,變數名2,...
示例見:
nonlocal.py
v = 100
def f1():
v = 200
print("f1.v=",v)
def f2():
nonlocal v
v = 300
print("f2.v=",v)
f2()
print("呼叫f2()後的f1.v=",v)
f1()
print("全域性的v=",v)
#結果為:
# f1.v= 200
# f2.v= 300
# 呼叫f2()後的f1.v= 300
# 全域性的v= 100
說明:
1.nonlocal 語句只能被巢狀函式的內部進行使用
def fx():
nonlocal v
v = 100
#沒有巢狀不能使用
2.訪問nonlocal變數進行賦值操作,將對外部巢狀函式作用域內的
變數進行操作
3.當有兩層或兩層以上函式巢狀時,訪問nonlocal變數只是
對近一層變數進行操作
示例見nonlocal2.py
def f1():
v = 200
def f2():
v = 300
def f3():
nonlocal v #修改f2中的區域性變數v
v = 400
f3()
print("f2.v",v)
f2()
print("f1.v",v)
f1()
#結果是
# f2.v 400
# f1.v 200
4.nonlocal語句的變數列表裡的變數名,不能出現在此函式形參列表中
def 語句
語法:
def 變數名/函式名(形參):
語句塊
lambda 表示式
作用:
建立一個匿名函式物件
同def 類似,但不提供函式名
語法:
lambda [形參名1,形參名2,....]:表示式
示例見:
lambda.py
# def myadd(x, y):
# return x + y
# 等同於
myadd = lambda x, y: x + y #建立函式
print('20 + 30 =',myadd(20, 30))
print('40 + 50 =',myadd(40, 50))
fx = lambda:print("hello world!")
fx()
# hello wprld!
語法說明:
1.lambda只是一個表示式,它用來建立一個函式
2.當lambda表示式呼叫時,先執行(:) 後的表示式,並返回表示式的結果的引用
3.lambda表示式建立的函式只能包含一條表示式
4.lambda比函式簡單且可以隨時建立和銷燬,有利於減少程式的偶合度
(形參越少對外界依賴程度越小,偶合度越低的程式越好)
練習二:
1.寫一個lambda表示式,建立一個函式,此函式判斷引數n 的平方
加1能否被5整除,如果能整除返回True,否則返回False
fx = lambda n:...
print(fx(3)) #True
print(fx(4)) #False
fx = lambda n: True if (n ** 2 + 1) % 5 == 0 else False
# fx = lambda n:(n ** 2 + 1) % 5 == 0
print(fx(3))
print(fx(4))
2.寫一個lambda表示式,返回兩個形參的最大值
def mymax(x, y):
...
mymax = lambda...
print(mymax(100,200)) #200
def mymax(x, y):
if x > y:
return x
else:
return y
mymax = lambda x, y:max(x, y)
#mymax = lambda x, y:x if x > y else y
print(mymax(100,200))
看懂下面的程式在做什麼?
def fx(f, x, y):
print(f(x, y))
fx((lambda a, b:a + b),100,200)
fx((lambda x, y:x ** y),3,4)
#lambda附給f
eval,exec函式
eval()函式
作用:
把一個字元當成一個表示式來執行,返回表示式執行後的結果
注:eval只能給表示式不能給語句
格式:
eval(source, globals=None, locals=None)
示例見:
eval.py
x = 100
y = 200
s = "x + y"
a = eval(s) #解釋執行s字串,把表示式的值返回回來
print(a) #300
b = eval(s,None,{'x':1,'y':2})
print(b) #3
c = eval(s,{'x':10,'y':20},{'x':1})
print(c) #21
exec()函式
作用:
把一個字串當成一個程式來執行
格式:
exec(source, globals=None, locals=None)
示例:
s = "x=100\ny=200\nprint('x+y=',x+y)\ndel x, y"
exec(s)
課後練習:
1.給出一個數n,寫一個函式myfac(n)來計算n!(n的階乘)
n! = 1*2*3*4*5*....*n
print(myfac(5)) #120
2.給出一個數n,寫一個函式計算:
1 +2**2+3**3+4**4+....+n**n的和
3.寫程式列印楊輝三角(只打印六層)
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1