python淺學筆記2 函式

2021-09-12 02:46:50 字數 4642 閱讀 1422

==漢諾塔==

時間戳:2023年3月6日23:38:55

常用函式呼叫 abs() max() float() str() bool() hex()isinstance(x,(int,str))

定義乙個函式 使用關鍵字 def 例如:

def

my_abs

(x):

if x:

return x

else

:return

-x

如果沒有return語句,函式返回none

定義乙個空函式

def

nop():

pass

pass可以作為佔位符,充當乙個能代替乙個將要完成的**塊

在命令列匯入某個檔案的某個函式 from 檔名 import 函式名

函式可以返回多個值,在return 語句中用 , 隔開return返回的真是值其實是乙個單一的tuple,tuple在return語句中可以省略括號,並且用多個引數來接受這個tuple

python有必選引數、預設引數、可變引數和關鍵字引數

def

f1(x)

:#x為必選引數

print

(x)def

f2(x,y =1)

:#x為必選引數,y為預設引數,必選在前,預設在後

print

(x,y)

deff3

(x =

1,y =2)

:print

(x,y)

#多個預設引數的呼叫

f3()

# x = 1,y = 2

f3(3

)# x = 3,y = 2

f3(3,4

)# x = 3,y = 4

f3(y=2)

# x = 1,y = 2

定義預設引數時,引數一定要是不可變引數

如果定義成可變引數會有乙個大坑。如:

def

f(x =

):'end'

)print

(x)f(

)# 列印['end']f()

# 列印['end','end']f()

# 列印['end','end','end']

發生了什麼?在定義函式 f 時,x引數被預設繫結的值 是 指向物件 的引用在以後使用預設值呼叫f時,永遠都使用最初定義的那個引用

在python中不變物件好像很重要的樣子,還有多工環境(是多執行緒嗎)對這些物件處理

即函式的引數個數可變

deff(

*x):

for m in x:

print

(m)f(1)

# print(1)f(1

,2,3

)# print(1) print(2) print(3)f(*

[1,2

,3,4

,7])

#呼叫可變引數的函式,可以用前面標*的 list 或 tuple 傳入

可變引數的呼叫,實質上會把傳入的引數在底層包裝成乙個tuple做處理

即可為函式傳入帶有引數名的引數,並且引數數量可變,多應用於介面的擴充套件,讓呼叫者可以提供更多資訊

方法,用雙*標識引數dict,傳入dict的備份

def

f(x,

**kv)

:print

(kw)

f(10

,hello =

'jim'

)#傳入了變數hello

extrainfo =

f(**extrainfo)

#傳入了變數 money,傳入了extrainfo的乙個備份,在函式中的操作並不會改變變數extrainfo

普通關鍵字引數,變數名不受限制。如果命名了關鍵字引數則可以限制關鍵字引數的名稱

方法用乙個 *變數 或者 可變引數 *x 變數隔開,這樣命名的關鍵字引數就變成了必選的引數,它們的傳入順序是可變的,當然也可以給關鍵字引數預設乙個值,這樣傳入時就可預設該關鍵字。

def

f(x,y,

*,city,room)

:pass f(

1,2,city =

3,room =4)

f(1,2

,room =

4,city =3)

defff

(x,y,

*,city,room =1)

:pass

ff(1,

2,city =

3)

以上幾種引數可以組合起來使用,但是要遵守定義順序,從前到後,分別是必選引數、預設引數、可變引數、命名關鍵字引數和關鍵字引數。

def

f(x,y =1,

*args,city,room,desk =1,

**kv)

:print

(x,y,args,city,room,desk,kv)

pass

f(10,11

,12,13

,city =

20,room =30)

#print: 10 11 (12, 13) 20 30 1 {}

函式內部呼叫函式本身

最經典的是階乘的計算

n! = 1 * 2 * 3 * 4*…* n

用fact(n)計算結果:

def

fact

(n):

if n ==1:

return

1else

:return n * fact(n-

1)

理解 n * fact(n-1)

fact(n-1) 可以視為 (n-1)*fact(n-2)

fact(n-2) 可以視為 (n-2)*fact(n-3) …

歸納, n * (n-1) * (n - 2) * (n - 3)… 2 * f(1)

使用遞迴函式要注意防止棧溢位,計算機中函式呼叫是通過棧(stack)結構實現。棧的大小是一定的,類似的比如另一種解釋型語言lua的函式呼叫棧是200,超過200個函式的呼叫就會報錯。即在lua 呼叫fact(201) 就會導致程式報錯。

為防止函式呼叫棧溢位,可以使用尾遞迴進行優化,即 return 後邊的表示式只能是函式的呼叫,不能有其他對函式f的計算。這樣每次呼叫時都退出上一次的呼叫,只會占用棧的1個位置。但很遺憾的是大多數程式語言包括python都沒有對尾呼叫進行優化

def

f(x)

:if x:

x--return f(x)

else

:return

1

我測試了一下,如果不使用尾呼叫,fact(999),就會報錯recursionerror: maximum recursion depth exceeded in comparison;使用了尾呼叫依舊會報同樣的錯誤

尾呼叫的效果是和迴圈一樣的。python居然沒有for的步長迴圈。

a b c三個柱子,a柱子套著n個從下到上且從大到小的圓環,b,c 是空柱子,借助b柱,將a柱所有圓環按順序套在c柱上。移動過程中,每次只能移動乙個圓環,並且小圓環上不能套大圓環。

使用遞迴方法編寫函式 move(n,a,b,c)

#aa = ,,]} #src

#aa = ]} #src

aa =,,

]}#src

bb =

#assist

cc =

#dest

defmove

(n,src,assist,dest)

:if n ==1:

moveonce(src,dest)

else

: move(n-

1,src,dest,assist)

move(

1,src,assist,dest)

move(n-

1,assist,src,dest)

defmoveonce

(src,dest)

: circle = src[

'list'

].pop(

) dest[

'list'

]print

(src[

'name'],

'-->'

,dest[

'name'])

print

(aa,bb,cc)

move(

len(aa[

'list'])

,aa,bb,cc)

>>

>輸出:

a --

> c,]

}]}a -

-> b]}

]}]}

c --

> b]}

,]}a -

-> c,]

}]}b -

-> a]}

]}]}

b --

> c]}

,]}a -

-> c,,

]}

python淺學筆記20 非同步IO

cpu速度遠遠快於 網路 磁碟 io 在乙個執行緒裡,io會阻塞其它 的執行。為了不阻塞,就要用多執行緒或多程序,雖然併發可以解決這個問題,但是系統不能無上限的增加執行緒,系統切換執行緒的開銷也很大 另一種解決問題的方法非同步io,cpu負責 的執行,io操作由io裝置執行,負責開啟乙個io操作,並...

linux C淺學大綱 2

define start 2018.1.5號是意義非凡的一天。寫之前說明下為什麼寫,怎樣寫,怎樣學。本人,小白。在某培訓機構培訓了幾個月,寫出來的東西,膚淺,有誤,請賜教。此文章,寫給那些,想學,卻摸不到大綱的同仁。二.基礎知識擴充套件 學習linux c之前,應該先掌握,標準c語言基本知識。1 鍊...

python淺學筆記9 IO程式設計

stringio和bytesio 操作檔案和目錄 序列化 pickling name input output face 磁碟,網路 model stream 流 from to 記憶體 time stop?同步 非同步 由於非同步io比較複雜,本章都是同步io,非同步io在後邊網路伺服器提及。開啟...