函數,參數及作用域
創建函數
- 使用def語句定義函數
# 定義函數
def fibs(num):
result = [0, 1]
for i in range(num-2):
result.append(result[-2]+result[-1])
return result
- 文檔化函數
如果想要給函數寫文檔的,讓其他使用者便於理解的話,可以加入註釋(以#開頭),另外一種方式就是寫上字符串,在def語句後面及在模塊或者類的開頭
def sqare(num):
"返回傳入參數的平方"
return num*num
#訪問文檔字符串
print(sqare.__doc__)
- 函數返回值
所有的函數都返回了東西,當沒有返回值的時候,就返回None。
def test():
print("會執行")
return
print("不會執行")
x = test()
print(x)
#執行結果
會執行
None
參數
- 形參實參
寫在def語句中函數名後面的變量通常叫做函數的形參,而調用函數的時候提供的值是實參,或者稱爲參數 - 參數可以改變嗎
參數存儲在局部作用域內,在函數內爲參數賦予新值不會改變外部的任何變量
# 傳入參數是否會被改變
# 1. 傳入參數是否會被改變(字符串,數字,元組)
def to_change(n):
return n*n
x = 3
a = to_change(x)
print("x = ", x,"a = ",a)
# 2. 傳入參數是否會被改變(列表)
# 本例中,參數被改變了,這是因爲兩個變量同時引用一個列表的時候,他們的確是同時引用一個列表
def change(n):
n[0] = "hello python"
lis = ["hello", "world"]
change(lis)
print(lis)
# 3. 傳入參數是否會被改變(列表副本)
# 切片會返回副本
names = ["hello", "world"]
change(names[:])
print(names)
# 4. 需要修改參數的情況(初始化)
def init(data):
data["first"] = {}
data["middle"] = {}
data["last"] = {}
storage = {}
init(storage)
print(storage)
#執行結果
x = 3 a = 9
['hello python', 'world']
['hello', 'world']
{'first': {}, 'middle': {}, 'last': {}}
- 關鍵字參數和默認值
# 關鍵字參數 提供參數名字,便於記憶;提供默認值
def hello_1(greeting = "hello", name = "world"):
print(greeting, name)
def hello_2(name="world", greeting="hello"):
print(greeting, name)
hello_1()
hello_1("test")
hello_2(greeting = "test")
# 執行結果
hello world
test world
tast world
- 收集參數
函數接收任意多的參數
# 接受任意多的參數 返回元組
def print_params(*params):
print(params)
print_params()
print_params("test")
print_params(1,2,3)
# 與普通參數聯合使用
def print_params_2(title, *params):
print(title)
print_params(params)
print_params_2("Params: ", 1,2,3)
# 處理關鍵字參數 返回字典
def print_params_3(**params):
print(params)
print_params_3(x = 1, y = 2, z = 3)
# 組合使用
def print_params_4(x, y, z=3, *pospar, **keypar):
print(x, y, z)
print("pospar =", pospar)
print("keypar=", keypar)
print_params_4(1, 2, 3, 5, 6, 7, a=1, b=2)
print_params_4(1, 2)
()
('test',)
(1, 2, 3)
Params:
((1, 2, 3),)
{'x': 1, 'y': 2, 'z': 3}
1 2 3
pospar = (5, 6, 7)
keypar= {'a': 1, 'b': 2}
1 2 3
pospar = ()
keypar= {}
作用域
出來全局作用域之外,每個函數調用都會創建一個新的作用域
# 作用域
def foo(): x =42
x = 1
foo()
print(x)
#執行結果
1
# 函數內部訪問全局變量
a = 1
b = 10
def foo_1():
b =5
print(a)
# 全局變量會被重名的局部變量屏蔽 使用globals函數
print(b)
print("globals_b =", globals()["b"])
foo_1()
#執行結果
1
5
globals_b = 10
# 重新綁定全局變量 使用global函數
def foo_2():
global s
s = 3
s = 1
foo_2()
print("s =",s)
#執行結果
s = 3
- 嵌套作用域
# 閉包 函數存儲子封閉作用域 函數本身被返回了,但並沒有被調用
def multipplier(factor):
def multipByFactor(number):
return number*factor
return multipByFactor
double = multipplier(2)
print(double(2)) # 4
triple = multipplier(3)
print(triple(2)) # 6
遞歸
- 階乘和冪
# 階乘 遞歸方式實現
'''
1. 1的階乘是1
2. 大於1的數n的階乘是n乘n-1的階乘
'''
def factorial(n):
if n == 1:
return 1
else:
return n * factorial(n-1)
print(factorial(4))
# power(x, n)(x爲n的冪次)
'''
1. 對於任意數字來說,power(x, 0)是1
2. 對於任何大於0的數來說,power(x, n)是x乘以power(x, n-1)的結果
'''
def power(x, n):
if n == 0:
return 1
else:
return x * power(x, n-1)
print(power(3,3))