python基礎-10-函數

一、函數

  當我們在編寫程序時。可能會遇到某些功能相似的代碼。此時爲了減少代碼冗餘,我們可以使用將功能相似的代碼寫成一個函數,並在適當的位置調用。

二、函數定義

引入一個關鍵字 def 用於定義一個函數

  • 它必須後跟函數名稱帶括號的形式參數列表
  • 構成函數體的語句從下一行開始,並且必須縮進
  • 函數體的第一個語句可以(可選的)是字符串文字; 它是函數文檔字符串, 用於解釋函數的功能, 及參數和返回值的含義
  • 函數的 執行 會引入一個用於函數局部變量的新符號表。 更確切地說,函數中所有的變量賦值都將存儲在局部符號表中;
    • 變量引用會首先在局部符號表中查找
    • 然後是外層函數的局部符號表
    • 再然後是全局符號表
    • 最後是內置名稱的符號表

語法規則

def function_name(形參列表):
	"""函數文檔""" [可選]
	函數執行的代碼
	return 返回值
  • 函數被調用時,實際參數會被引入被調用函數的本地符號表中;實參是通過 按值調用傳遞的
    • 其中 始終是對象引用: 即使對象的id
    • 不是對象的值
    • 函數調用是通過 函數名(形參列表) 形式調用
  • 當一個函數調用另外一個函數時,將會爲該調用創建一個新的本地符號表。
  • 即使沒有 return 語句的函數也會返回一個值,這個值稱爲 None (它是內置名稱)

示例程序

def fib(n):
    a, b = 0, 1
    while a < n:
        print(a, end=" ")
        a, b = b, a+b
    print()


fib(10)  # 函數調用


def fib2(n):
    result = []
    a, b = 0, 1
    while a < n:
        result.append(a)
        a, b = b, a+b
    return result


print(fib2(10))

三、函數的參數形式

上面示例程序中的函數參數是必備參數形式. 即在調用函數時, 必須傳入參數到函數中. 否則會報錯.

3.1 空參數形式

函數不需要參數就能被調用.

def printf():
	print("hello world")

3.2 參數默認值

對一個或多個參數指定一個默認值。這樣創建的函數,可以用比定義時允許的更少的參數調用.

def function_name(agr1=value1,arg2=value2):
    函數內執行代碼
  • 默認值是在函數定義處計算
    i = 10
    def print_i(arg=i):
    	print(arg)  # 輸出的是10
    	print(i)  # 輸出6
    i = 6
    print_i()
    
  • 默認值只會執行一次
    def fun(a, L=[]):
    	L.append(a)
    	return L
    	
    print(fun(1))  # 輸出[1] 
    print(fun(2))  # 輸出[1, 2]
    print(fun(3))  # 輸出[1, 2, 3]
    
    • 如果你不想要在後續調用之間 共享默認值, 函數進行如下定義:
    def fun(a, L=None):
    	if L is None:
        	L = []
    	L.append(a)
    	return L
    
    print(fun(1))  # 輸出[1]
    print(fun(2))  # 輸出[2]
    print(fun(3))  # 輸出[3]
    

3.3 不定長參數形式

有時候函數需要很多的參數, 如果全部顯示寫出來會顯得函數定義臃腫. 可以使用不定長參數來定義函數
語法如下

def function_name(*args, **kwargs):
    函數內執行代碼
  • *args當以變量形式直接傳入多個參數時,會被*args接收並打包成元組的形式存在args中傳入函數內。
  • **kwargs 當以映射(默認參數)的形式傳入參數時,會被**kwargs接收並打包成字典形式存在kwargs中傳入函數內

3.4 特殊參數/ *

默認情況下,函數的參數傳遞形式可以是位置參數或是顯式的關鍵字參數。 爲了確保可讀性和運行效率,限制允許的參數傳遞形式是有意義的,這樣開發者只需查看函數定義即可確定參數項是僅按位置、按位置也按關鍵字,還是僅按關鍵字傳遞。
函數的定義看起來可以像是這樣:

def f(pos1, pos2, /, pos_or_kwd, *, kwd1, kwd2):
      -----------    ----------     ----------
        |             |                  |
        |        Positional or keyword   |
        |                                - Keyword only
         -- Positional only
  • 如果函數定義中未使用 /*,則參數可以按位置或按關鍵字傳遞給函數。
  • 如果使用了/, 則/之前的參數只能通過位置傳參; 之後的參數可以通過位置傳參, 也可以同關鍵字傳參
  • 如果使用了*, 則*之後的參數必須以關鍵字傳參

3.5 解包參數

  1. 通過*操作符來將列表或元組解包用於位置參數傳遞
  2. 通過**操作符來將字典解包用於關鍵字參數的傳遞

四、函數的標註

針對函數參數和返回值類型的說明
語法格式如下

def function_name(arg1: 類型, arg2: 類型 = "默認值")-> 類型:
	函數執行的代碼

五、閉包

閉包是指在函數內部嵌套一個函數,可由外層函數返回內層函數的函數名。

def func():
    def text():
        print("hello world")
    return text

text = func()  # 調用外層函數獲取內層函數函數名

text()  # 調用內層函數。

閉包是函數裏面嵌套函數,外層函數返回裏層函數,這種情況稱之爲閉包

閉包是概念,不是某種函數類型,和遞歸的概念類似,就是種特殊的函數調用

閉包可以得到外層函數的局部變量,是函數內部和函數外部溝通的橋樑

六、變量的作用域

  1. 函數內部可以查看函數外部的變量, 但是不能修改函數外部變量.
  2. 函數內部變量不能在函數外部使用.

全局變量
可以在程序任意位置訪問的的變量稱爲全局變量.

局部變量
只能在特定位置訪問的變量稱爲局部變量. 比如函數內的定義的變量, 控制語句中定義的變量.

6.1 全局變量的使用

python中函數內部是不能修改函數外部的變量的. 要使用關鍵字global在函數內部聲明全局變量, 才能對全局變量進行修改

global_int = 12

def func():
    global global_int
    global_int += 1
    print('函數內部',global_int)

func()
print('函數外部',global_int)

6.2 局部變量的使用

定義在函數內部的變量. 如果內層函數要修改外層函數的變量使用關鍵字nonlocal聲明局部變量, 這樣才能在內層函數修改外層函數的變量

def glo():
    test_non = 34
    print("外部函數", test_non)
    def test():
        nonlocal test_non
        test_non += 1
        print('內部測試函數', test_non)

    return test
glo()()

面向對象

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章