一、可調用類型
在 python中所有的類型都是對象,即使是 int,float這些其他語言中的基礎類型在 python中也是以對象的形式存在,函數和方法也不例外。
在 python中函數和方法是可調用類型的兩個子集,可調用類型一共有 5種:
類型名稱 | 描述 |
---|---|
types.BuiltinFunctionType | 內置函數或方法 |
type | 內置類型和類的類型 |
object | 所有類和類型的祖先 |
types.FunctionType | 用戶定義的函數 |
types.MethodType | 類方法 |
最後兩種就是我們常說的函數和方法,函數在類外被定義,而方法在類裏面被定義,我們也可以說方法是類裏面的函數,如:
# 在類外定義的是函數 def function_1(): print("Hello World. This is a function.") class TestClass: # 在類裏面定義的是方法 def function_2(): print("Hello World. This is a method.")
需要注意的是,在 C++、JAVA這些面向對象的語言中函數和方法指的是同一個概念,它們沒有像 python一樣做出類型區分,只是在叫法上有些區別而已。
在這篇教程中我們只講函數,至於方法等我們講到類的時候再詳細地講,在這之前大家像用函數一樣用方法就行。
二、函數的屬性
前面我們講到每個函數都是一個對象,對象自然有對應的屬性:
-
__doc__
:函數的註釋,就是緊挨着函數名的一個字符串,用來註釋函數,文檔生產工具可以根據這些字符串生成對應的文檔,如: def f(name="name"): """ This is a function. """ pass print(f.__doc__) """ This is a function. """ -
__name__
:函數的名字,如: def function_name(): pass print(function_name.__name__) # function_name -
__defaults__
:包含默認參數名的元組,如: def function_defaults(args_1, args_2='name'): pass print(function_defaults.__defaults__) # ('name',)
三、函數的參數
函數的參數有兩種,位置參數和關鍵字參數,這兩者又分爲有默認值和沒有默認值兩種類型。
位置參數和關鍵字參數的主要區別是,位置參數在傳遞的時候可以不指定變量名,而是按照約定的順序進行賦值,而關鍵字參數必須指定變量名才能對其進行賦值,如:
def function_args(a1, a2): print("a1:", a1, "a2", a2) function_args('1','2') # a1: 1 a2 2 # a1和 a2都是位置參數,第一個參數賦值給 a1,第二個參數賦值給 a2 def function_keyword_args(a1, *, a2): print("a1:", a1, "a2", a2) function_keyword_args('1', a2='2') # 此時再使用 function_keyword_args('1', '2')會報錯 # 因爲 a2是關鍵字參數,必須指定變量名
所有的參數默認爲位置參數,只有當使用 *分隔時後面的參數纔會被看作關鍵字參數。
注意:
在定義函數時上面四種參數的書寫順序是有嚴格限制的,位置參數必須聲明在最前面,同時有默認值的參數必須在沒有默認值的參數後面,如:
def function_args(a1, a2='2', *, a3, a4='4'): print("a1:", a1, "a2", a2, "a3:", a3, "a4:", a4) # 下面的定義是錯誤的 # 有默認值的參數在前 def function_args(a2='2', a1, *, a3, a4='4'): print("a1:", a1, "a2", a2, "a3:", a3, "a4:", a4)
當我們有很多參數要傳遞給函數時,我們可能會寫出這樣的代碼:
def function_args(a1, a2, a3, a4, a5, a6, *, b1, b2, b3, b4): pass function_args(1, 2, 3, 4, 5, 6, b1=1, b2=2, b3=3, b4=4)
這樣的代碼可以說是很糟糕的代碼了,這時我們可以使用 *
和 **
來簡化我們的代碼,如:
def function_args(a1, a2, a3, a4, a5, a6, *, b1, b2, b3, b4): pass args = [1, 2, 3, 4, 5, 6] # 或者 args = (1, 2, 3, 4, 5, 6) keyword_args = { 'b1': 1, 'b2': 2, 'b3': 3, 'b4': 4 } function_args(*ags, **keyword_args)
*
的操作對象是列表或者元組,用來傳遞位置參數,**
的操作對象是字典,用來傳遞關鍵字參數。
四、函數作爲變量使用
既然函數是一種特殊的變量類型,那變量所具有的操作肯定也可以應用到函數上,比如:
- 賦值給其他變量: def say_hello(): print("Hello World") say_hello_2 = say_hello say_hello_2() # Hello World
- 作爲參數傳遞 def say_hello(): print("Hello World") def execute_func(func): func() execute_func(say_hello) # Hello World