Python基礎4 函數
函數基本語法及特性
函數是什麽?
定義:
函數是指將一組語句的集合通過一個名字(函數名)封裝起來,要想執行這個函數,只需調用其函數名即可。
特性:
減少重復代碼
使程序變的可擴展
使程序變的易維護
def sayhi(): # 函數名
print(‘Hi, I‘m Jack!‘)
sayhi() # 調用函數
函數也可以帶參數
def test(x, y):
print(x, y)
test(1,2)
函數參數與局部變量
形參:
變量只有在被調用時才分配內存單元,在調用結束時,即刻釋放所分配的內存單元。因此,形參只在函數內部有效。函數調用結束返回主調用函數後則不能再使用該形參變量。
實參:
可以是常量、變量、表達式、函數等,無論實參是何種類型的量,在進行函數調用時,它們都必須有確定的值,以便把這些值傳送給形參。因此應預先用賦值,輸入等辦法使參數獲得確定值。
def test(x, y): # x, y為形式參數
print(x + y)
test(1, 2) # 1, 2為實際參數
默認參數:
def test(x, y, z=3): # z為默認參數
print(x + y + z)
test(1, 2) # 在函數調用時,可以不給z傳值,如果不傳則該參數的值為3
關鍵字參數:
正常情況下,給函數傳參數要按順序,不想按順序就可以用關鍵參數,只需指定參數名即可,但記住一個要求就是,關鍵參數必須放在位置參數之後。
def test(x, y, z):
print(x + y + z)
test(1, z=3, y=10) # 這裏調用test函數時,先將位置參數1賦值給x再將z、y以關鍵字參數形式傳入函數中
非固定參數:
若你的函數在定義時不確定用戶想傳入多少個參數,就可以使用非固定參數,*args 會把多傳入的參數變成一個元組形式。
def test(x, y, *args):
print(‘x, y, *args‘, x, y, args)
test(1, 2, 3, 4)
>>> x, y, *args 1 2 (3, 4)
還可以有一個**kwargs,*kwargs 會把多傳入的參數變成一個dict形式。
def test(x, y, *args, **kwargs):
print(‘x, y, *args, **kwargs‘, x, y, args, kwargs)
test(1, 2, 3, 4, a=5, b=6, c=7)
>>>x, y, *args, **kwargs 1 2 (3, 4) {‘c‘: 7, ‘a‘: 5, ‘b‘: 6}
局部變量
name = ‘Jack‘
def test(name):
name = ‘Tom‘
print(‘My name is ‘, name)
test(‘name‘)
函數會從自身查name變量去調用
全局變量與局部變量
在子程序中定義的變量稱為局部變量,在程序的一開始定義的變量稱為全局變量。 全局變量作用域是整個程序,局部變量作用域是定義該變量的子程序。 當全局變量與局部變量同名時: 在定義局部變量的子程序內,局部變量起作用;在其它地方全局變量起作用。返回值
要想獲取函數的執行結果,就可以用return語句把結果返回註意:
函數在執行過程中只要遇到return語句,就會停止執行並返回結果,也可以理解為 return 語句代表著函數的結束
如果未在函數中指定return,那這個函數的返回值為None
嵌套函數
name = ‘Tom‘
def change_name1():
name = ‘Tom1‘
def change_name2():
name = ‘Tom2‘
print(name)
change_name2()
print(name)
change_name1()
print(name)
遞歸
遞歸特性:
必須有一個明確的結束條件
每次進入更深一層遞歸時,問題規模相比上次遞歸都應有所減少
遞歸效率不高,遞歸層次過多會導致棧溢出(在計算機中,函數調用是通過棧(stack)這種數據結構實現的,每當進入一個函數調用,棧就會加一層棧幀,每當函數返回,棧就會減一層棧幀。由於棧的大小不是無限的,所以,遞歸調用的次數過多,會導致棧溢出)
def calc(n):
print(n)
if int(n/2) == 0:
return n
print(‘----‘)
return calc(int(n/2))
calc(10)
匿名函數
匿名函數就是不需要顯式的指定函數
def calc(n):
return n*n
print(calc(10))
# 匿名函數
calc = lambda n: n*n
print(calc(10))
高階函數
變量可以指向函數,函數的參數能接收變量,那麽一個函數就可以接收另一個函數作為參數,這種函數就稱之為高階函數。
def add(x, y, f):
return f(x) + f(y)
res = add(-3, 4, abs)
print(res)
叠代器、生成器、裝飾器
叠代器
凡是可作用與for循環的對象都是可叠代對象
凡是可作用於next()函數的對象都是叠代器類型,表示一個惰性計算的序列
集合數據類型是可叠代對象,但不是叠代器,可通過iter()函數獲得一個叠代器對象
Python的for循環本質上是通過不斷調用next()函數實現的
import time
def consumer(name):
print ("%s 準備吃包子啦!" % name)
while True:
baozi = yield
print ("包子[%s]來了,被[%s]吃了" % (baozi,name))
def producer():
c1 = consumer("Jack")
c2 = consumer("Tom")
c1.__next__()
c2.__next__()
for i in range(1,11):
time.sleep(1)
print ("做好1個包子,分成兩份!")
c1.send(i)
c2.send(i)
producer()
生成器
#列表生成式
list1 = [i*2 for i in range(1,11)]
list = (x*2 for x in range(1,1000000))
#函數生成器
def fib(max):
n,a,b = 0,0,1
while n < max:
#print (b)
yield b
a,b = b,a+b
n = n + 1
#return異常的時候打印消息
return "done"
g = fib(10)
while True:
try:
x = next(g)
print ("g:",x)
except StopIteration as e:
print ("Generator return value:",e.value)
break
裝飾器
本身是函數,(裝飾其他函數)就是為其他函數添加附加功能
原則:
不能修改被裝飾的函數的源代碼
不能修改被裝飾的函數的調用方式
實現裝飾器知識儲備:
函數即“變量”
高階函數
嵌套函數
高階函數+嵌套函數=》裝飾器
def logging(func):
def warpper(*args,**kwargs):
func(*args,**kwargs)
print("logging...")
return warpper
@logging
def test1(name,age):
print("func in %s,%s" % (name,age))
@logging
def test2(name,age):
print("func in %s,%s" % (name,age))
Python基礎4 函數