Day6 函式的作用域 引數 eval 遞迴

2021-10-07 15:02:28 字數 4899 閱讀 6333

lambda表示式和匿名函式

eval()函式

遞迴函式

python中,「一切都是物件」。實際上,執行def定義函式後,系統就建立了相應的函式物件。

def

func1()

:print

("new pants"

)func1(

)c = func1 # 把func1的記憶體位址賦值給了c

print

(func1, c)

# c(

)# c()也可以呼叫fucn1函式

def

func1()

: b =

4# 區域性變數

print

(b *10)

print

(a)# local variable 'a' referenced before assignment,此處a被當作區域性變數

a =300# 在print(a)之前,還未定義a=300,所以出現如上報錯

print

(a)func1(

)# 當執行函式fucn1()時,在棧內建立棧幀(stack frame),執行結束,棧幀就不存在了

func1(

)# 不能在函式外呼叫區域性變數,如print(b),則報錯

a =

3# 全域性變數

deffunc1()

: b =

4# 區域性變數

print

(b *10)

global a # 如果要在函式內改變全域性變數的值,增加global關鍵字宣告

a =300# 在print(a)之前,還未定義a=300,所以出現如上報錯

print

("區域性"

,locals()

)# 列印輸出的區域性變數

#區域性

print

("全域性"

,globals()

)# 列印輸出的全域性變數

'''全域性 , '__builtins__': , '__file__': 'd:/tools/pythonproject/mytest/day_6/函式變數的作用域.py', '__cached__': none, 'a': 300, 'func1': }

'''func1(

)print

(a)# 此時全域性變數a的值變為300

import math

import time

# 區域性變數的查詢和訪問速度比全域性變數快

deffunc1()

: start = time.time(

)for i in

range

(10000000):

math.sqrt(30)

# 呼叫了全域性的import math

end = time.time(

)print

("耗時"

.format

((end - start)))

# 耗時1.1883010864257812

func1(

)def

func2()

: start = time.time(

) b = math.sqrt

for i in

range

(10000000):

b(30)

# 從區域性去引用math.sqrt

end = time.time(

)print

("耗時"

.format

((end - start)))

# 耗時0.8516945838928223

func2(

)

函式的引數傳遞本質上就是:從實參到形參的賦值操作。python中「一切皆物件」,所有的賦值操作都是「引用的賦值」。所以,python中引數的傳遞都是「引用傳遞」,不是「值傳遞」。具體操作時分為兩類:

# 傳遞可變物件

a =[10,

20]print(id

(a))

print

(a)print

("********"

)def

func1

(m):

print(id

(m))30)

print(id

(m))

func1(a)

print(id

(a))

print

(a)# 三次列印id(a),記憶體位址都是2093959504456

def

func1

(a, b, c, d)

:print

("------"

.format

(a, b, c, d)

)def

func2

(a, b, c=

10, d=15)

:# 預設值引數(c,d),必須位於其他引數後面!

print

("------"

.format

(a, b, c, d)

)func1(10,

20,30,

40)# 位置引數

# func1(10,20) #引數個數不匹配,報錯

func1(d=

20, b=

40, a=

10, c=

100)

# 命名引數,通過形參名稱來匹配,不用考慮引數循序

func2(2,

3)# 2--3--10--15

func2(2,

3,4)

# 2--3--4--15

可變引數指的是」可變數量的引數「。分兩種情況:

def

func1

(a, b,

*args)

:print

(a, b, args)

# 1 2 (3, 4, 5, 6)

print

(a, b,

*args)

# 1 2 3, 4, 5, 6

func1(1,

2,3,

4,5,

6)deffunc2

(a, b,

**kwargs)

:print

(a, b, kwargs)

# 1 2

# print(a, b, **kwargs) #報錯

func2(1,

2, name=

"gaoqi"

, age=18)

deffunc3

(a, b,

*args,

**kwargs)

:print

(a, b, args, kwargs)

# 1 2 (3, 4, 5)

func3(1,

2,3,

4,5, name=

"gaoqi"

, age=

18)

f =

lambda a, b, c, d: a * b * c * d

print

(f(2,3

,4,5

))# func1等同於lambda

deffunc1

(a, b, c, d)

:return a * b * c * d

# 把函式物件作為列表的元素,放到列表中

g =[

lambda a: a *2,

lambda b: b *3,

]print

(g[0](

6))# g[0]指的是函式物件lambda a: a * 2,g[0]()則對lambda進行呼叫

h =[func1, func1]

print

(h[0](

3,4,

5,6)

)

# 用途:可以直接使用從外部(server,檔案等)接收的字串

s ="print('abcde')"

eval

(s)a =

10b =

20c =

eval

("a+b"

)print

(c)dic1 =

dict

(a=100

, b=

200)

d =eval

("a+b"

)# 此處的a,b為之前定義的變數,即a=10,b=20

print

(d)d =

eval

("a+b"

, dic1)

print

(d)# 此處的a,b為字典dic1中的a,b,因此a=100,b=200

def

func1

(n):

print

("func01:"

, n)

if n ==0:

print

("over"

)else

: func1(n -1)

print

("func01***"

, n)

func1(

4)

# 使用遞迴函式計算階乘

deffactorial

(n):

if n ==1:

return

1else

:return n * factorial(n -1)

res = factorial(5)

print

(res)

Day6 遞迴函式

遞迴函式看的雲裡霧裡,廖雪峰大師給出的練習題我也沒搞懂,先mark下理解的,其他的後續再說 通過之前的學習已經知道,函式的內部是可以呼叫其他函式的,如果乙個函式在內部呼叫自身本身,那麼這個函式就是遞迴函式。定義乙個計算階乘n!的函式 n 1x2x3x4x xn,用函式來表示可以看出 jx n n 1...

Day 6 函式式程式設計

函式式程式設計就是封裝成乙個個函式,一次呼叫來完成複雜任務。函式式程式設計的乙個特點是,允許把函式本身作為引數傳入另乙個函式,還允許返回乙個函式!高階函式就是將函式的變數名作為引數傳入,內部再對該函式進行呼叫的函式。乙個簡單的高階函式如下 def add x,y,f return f x f y x...

Day 6 函式與模組

def函式名 引數列表 函式體 示例1 計算矩形面積 函式名 area 引數 width 和 height 返回值 width height def area width,height 1 return width height 必須引數,按順序傳入引數 其中,5,6 按順序傳入,預設傳入width...