Python遺漏知識點三 函數和lambda表達式
爲函數提供文檔:
def my_func(x, y):
'''
獲取兩個數值中較大數
'''
z = x if x>y else y
return z
help(my_func)
print(my_func.__doc__)
python函數可以返回多個值,Python會自動將多個返回值封裝成元組;Python提供序列解包功能,直接使用多個變量接受函數返回的多個值。
s, avg = sum_and_avg(my_list)
print(s)
print(avg)
函數的關鍵字:
-
位置參數:按照位置來傳遞參數
-
關鍵字參數:關鍵字參數和位置參數混合使用,關鍵字參數必須位於位置參數之後。
print(girth(4.2, width = 3.5))
-
參數默認值
# 形參名 = 默認值 def say_hi(name = '小明', message = '歡迎光臨'): print(name, '你好') print('消息是:', message) say_hi() say('小黑', '下次光臨')
由於python規定調用函數時關鍵字參數必須位於位置參數之後,因此在定義函數時指定默認值的參數(關鍵字參數)必須位於沒有默認值的參數值之後
def printTriangle(char, height = 5)
pass
-
參數收集 (個數可變參數)
python允許在形參前面加(*),這樣就意味着可以接受多個參數值,多個參數值被當成元組傳入。def test(*books, num): print(books) for i in books: print(b) print(num) # 可變參數位於第一個位置,那麼後面的參數需要以關鍵字參數形式傳遞,否則會被歸於可變參數中 test('a', 'b', 'c', num = 20)
python會將多個關鍵字參數收集成字典。需要在形式參數前面添加兩個星號。
def test(x, y, z = 3, *book, **scores): print(x, y, z) print(books) print(scores) test(1, 2, 3, '高數上', '高數下', '線代', 語文 = 100, 數學 = 99) # 注意關鍵字參數傳遞方式
-
逆向參數收集
指的是在程序已有列表、元組、字典等對象的前提,把他們的元素‘拆開’後給函數的參數。
逆向參數收集需要在傳入的列表、元組參數之前添加一個星號,在字典參數之前添加兩個星號。def test(name, message): print('用戶是:', name) print('歡迎信息:', message) my_list = ['xiaoming', 'welcome'] test(*my_list)
實際上,即使是支持收集的參數,如果程序需要將一個元組傳遞給該參數,那麼同樣需要使用逆向收集
def foo(name, *num):
print('name參數:', name)
print(nums參數:, nums)
my_tuple = (1, 2, 3)
foo('小明', *my_tuple)
字典也支持逆向收集,使用在實際參數前面加兩個星號
def test(book, price, information):
print('書名:', book, '價格:', price)
print(information)
my_dict = {'book': '高數上', 'price': 26, 'information': '同濟出版'}
test(**my_dict)
注意:字典逆向收集類似於關鍵字參數,所以字典的key需要與函數的形式參數名對應而不能隨便定義
Python參數傳遞機制都是值傳遞。就是講實際參數的副本(複製品),傳入函數中,而參數本身不受影響。
主函數有一個棧區,自定義的函數有一個棧區,執行自定義函數的時候,把實際參數的值複製一份到自定義函數棧中操作處理。
對於==可變對象==,也是使用值傳遞。但是定義一個可變對象,內存中有個兩個東西:對象本身和指向該對象的引用變量。引用變量也就是一個指針,它保存了可變對象的地址值。因此,傳遞給自定義函數的也是地址值,所以主函數和自定義函數會引用到同一個字典對象。
變量的作用域:
globals()、locals()、vars(object)
- 全局範圍內調用globals()和locals()函數都會得到所有全局變量組成的字典。
- 任意位置調用globals()都會的到所有全局變量字典。
- var(object)得到的是指定對象範圍內所有變量組成的變量字典,如果不傳入object參數,vars()作用和locals()作用完全相同。
- 使用gloabls()和locals()獲得的全局範圍的變量字典可以修改,會真正改變全局變量本身;但是通過locals()獲取的局部範圍內的變量字典,及時對它修改也不會影響局部變量。
全局變量默認可以在所有函數內被訪問,但如果在函數中定義了與全局變量同名的變量就會發生局部變量遮蔽全局變量的情形。
name = ‘xiaoming’
def test():
print(name)
name = ‘laowang’ # 報錯,顯示局部name變量沒有被定義
test()
解決方法:
-
訪問被遮蔽的全局變量
name = ‘xiaoming’
def test():
print(globals()[‘name’])
name = ‘laownag’test() print(name)
-
在函數中聲明全局變量
name = ‘xiaoming’
def test():
global name
print(name)
name = ‘laowang’ # 把全局變量改變了test() print(name)
封閉函數與局部函數概念:
def foo():
name = 'laowang'
def bar():
nonlocal name
print(name)
name = '小明'
bar()
foo()
- nonlocal與local功能類似,區別只是global用於訪問全局變量,而nonlocal用於聲明訪問當前局部函數所在的封閉函數內的局部變量
函數的高級內容(函數式編程):
- 使用函數變量
- 使用函數作爲函數形參
- 使用函數作爲返回值
局部函數與lambda函數:
lambda表達式只能是單行表達式;lambda本質就是匿名的單行函數體的函數。
def get_math_func(type):
result = 1
if type == 'square':
return lambda x: x * x
elif type == 'cube':
return lambda x: x*x*x
else:
return lambda x: (1+x)*x/2
math_func = get_math_func('cube')
print(math_func(3))
x = map(lambda x: x*x, range(8))
print([e for e in x])
y = map(lambda x: x*x if x%2 == 0 else 0, range(1, 8))
print([e for e in y])