天天看點

Python基礎------函數

(一)Python函數

  • 數學定義

    y = f(x),y是x的函數,x是自變量.y=f(x0,x1,…,xn)

    一個x隻能對應一個y,而一個y可以對應多個x

  • Python函數

    由若幹語句組成的語句塊,函數名稱,參數清單構成,它是組織代碼的最小單 元

    完成一定的功能

  • 函數的作用

    結構化程式設計對代碼的最近本的封裝,一般按照功能組織一段代碼

    封裝的目的為了複用,減少備援代碼

    代碼更加簡潔 美觀,可懂易讀

(二)函數定義

def 函數名(參數清單):
    函數體(代碼塊)
    [return 傳回值]
           

函數名就是辨別符,命名要求一樣,可以使用字母.數字.下劃線,但不能用數字開頭.

語句塊必須縮進,約定4個空格

Python的函數若沒有return語句,會隐式傳回一個None值

定義中的參數清單稱為形式參數,隻是一種符号表達(辨別符).簡稱形參.

(三)函數調用

函數定義,隻是聲明了一個函數,但他不被執行,需要調用執行

調用的方式,就是函數後加上小括号,如有必要在括号内填上參數

調用時寫的參數是實際參數,是實實在在傳入的值簡稱實參

def add(x,y):      #函數的定義
    result = x + y  # 函數體
    return result   # 傳回值
out = add(4,5)  #函數的調用.可能有傳回值,使用變量接收這個傳回值
print(out)     #print函數加上括号也是調用
           
  • 上面代碼解釋

    定義一個函數add,及函數名add,接受兩個參數

    該函數計算的結果,通過傳回值傳回,需要return語句

    調用時,通過函數名add後加2個參數,傳回值可使用變量接收

    函數名也是辨別符,傳回值也是值

    定義餘姚在調用前,也就是說調用時,已經被定義過了,否則泡NameError異常

    函數是可調用對象,callable()

(四)函數參數

函數在定義是要約定好形式參數,調用時也提供足夠的實際參數,一般來說,形參和實參個數要一緻(可變參數除外).

  • 傳參方式

    1,位置傳參

    定義def f(x,y,z),調用使用f(1,3,5),按照參數定義順序傳入實參

    2,關鍵字傳參

    定義時def f(x,y,z),調用使用 f(x=1,y=3,z=5),使用形參的名字來傳入實參的方式,如果使用了形參的名字,那麼傳參順序就可和定義順序不同

    要求位置參數必須在關鍵字參數之前傳入,位置參數是按位置對應的

def f(x,y,z):
    pass
f(z=None,y=10,x=[1])
f((1,),z=6,y=4.1)
           
  • 參數預設值

    預設值也稱為預設值,可以在函數定義時,為形參增加一個預設值.其作用:

    參數的預設值可以在未傳入足夠的實參的時候,對沒有給定的參數指派為預設值

    參數非常多的時候,并不需要使用者每次都輸入所有的參數,簡化函數調用

# 定義一個函數login,參數名稱為host,port,username,password
def login(host='127.0.0.1',port='8080',username='wayne',password='Python'):
    print('{}:{}@{}/{}'.format(host,port,username,passwd))



login()
login('127.0.0.1',80.'tom','tom')
login('127.0.0.1',username='root')
login('localhost',port=80,password='com')
login(port=80,password='Python',host='www')
           
  • 可變參數

    1,可變位置參數

    在形參前使用*表示該形參時可變位置參數,可以接受多個實參

    它将手機來的實參組織到一個tuple中

def sum(*nums):
    sum = 0
    for x in nums:
        sum += x
    return sum

print(sum[1,3,5])
           

2,可變關鍵字參數

在形參前使用**表示該形參時可變關鍵字參數,可以接受多個關鍵字參數

它将手機來的實參的名曾和值,組織到一個dict中

def showconfig(**kwargs):
    for k,v in kwargs.items():
        print('{}={}',format(k,v),end=',')

showconfig(host='127.0.0.1',port=8080,username='wayne',passwd='Python')
           
  • 總結

    有可變位置參數和可變關鍵字參數

    可變位置參數在形參前使用一個星号*

    可變關鍵字參數在形參前使用兩個星号**

    可變位置參數和可變關鍵字參數都可以收集若幹個實參,可變位置參數收內建形成一個tuple,可變關鍵字參數收集形成一個dict

    混合使用參數的時候,普通參數需要放到參數清單前面,可變參數要放到參數清單後面,可變位置參數需要在可變關鍵字參數之前

def fn(x,y,*args,**kwargs):
    print(x,y,args,kwargs,sep='\n',end='\n\n')

fn(3,5,7,9,10,a=1,b='abc')
fn(3,5)
fn(3,5,7)
fn(3,5,a=1,b='abc')
fn(x=3,y=8,7,9,a=1,b='abc')
# 錯在位置傳參必須在關鍵字傳參之前
fn(7,9,y=5,x=3,a=1,b='abc')
# 錯在7和9已經按照位置傳參了,x=3,y=5有重複傳參
           

(五)keyword-only參數

在形參定義時,在一個*星号之後,或一個可變位置參數之後,出現普通參數,就已經不是不同參數了,稱為keywaord-only參數.

def fn(*args,x):
    print(x.args,sep='\n',end='\n\n')

fn(3,5)# x沒有參數報錯,3,5被*args接收
fn(3,5,7)# x沒有參數報錯,3,5,7被*args接收
fn(3,5,x=7)
           

keyword-only參數,言下之意就是這個參數必須采用關鍵字傳參

可以認為,上例中args可變位置參數已經截獲了所有的位置參數,其後的變量x不可能通過位置傳參傳入.

  • **kwargs
def fn(**kwargs,x):
    print(x,kwargs,sep='\n',end='\n\n')
           

直接報文法錯誤

可以認為,kwargs會截獲所有關鍵字傳參,就算寫了x=5,x也沒有機會得到這個值,是以這種文法不存在

  • keyword-only參數另一種形式

    *星号後所有不同參數都成了keyword-only參數.

def fn(*,x,y):
    print(x,y)
fn(x=6,y=7)
fn(y=8,x=9)
           

(六)參數的混合使用

# 可變位置參數,keyword-only參數,預設值
def fn(*args,x=5)
    print(x)
    print(args)
fn()   #等價于fn(x=5)
fn(5)  #args=5 x=5
fn(x=6)     #x = 6
fn(1,2,3,x=10)  #args=(1,2,3) x=10
           
#普通參數,可變位置參數.keyword-only參數,預設值
def fn(y,*args,x=5)
    print('x={},y={}',format(x,y))
    print(args)
fn() # y沒有預設值,報錯
fn(5) # y=5 x=5
fn(5,6) # y=5 args=6 x=5
fn(x=6) #報錯 y沒有指派
fn(1,2,3,x=10) # y=1 args=(2,3) x=10
fn(y=17,2,3,x=10) # 報錯,2,3,沒有綁定形參
fn(1,2,y=3,x=10)  #報錯,先将1指派個y,2指派給args,又給y指派3,y有兩個值
           
# 普通參數,預設值,可變關鍵數參數
def fn(x=5,**kwargs):
    print('x={}'.format(x))
    print(kwargs)
fn()     # x=5
fn(5)   # x=5
fn(x=6)     # x=6
fn(y=3,x=10)    # x=10 {y:3}
fn(3,y=10)      # x=3 {y:10}
fn(y=3,z=20)    # x=5 {y:3,z:20}
           

(七)參數規則

參數規則清單參數一般順序時:普通參數,預設參數,可變位置參數,keyword-only參數(可帶預設值),可變關鍵字參數

  • 代碼應該易讀易懂,而不是為難别人
  • 請按照書寫習慣定義函數參數
def fn(x,y,z=3,*args,m=4,n,**kwargs):
    print(x,y,z,m,n)
    print(args)
    print(kwargs)
def connect(host='localhost',port='3306',user='admin',password='admin',**kwargs):
    print(host,port)
    print(user,password)
    print(kwargs)
connect(db='cmdb')
connect(host='192.168.1.123',db='cmdb')
connect(host='192.168.1.123',db='cmdb',password='mysql')
           
  • 定義最常用參數為普通函數,可不提供預設值,必須由使用者提供.注意這些參數的順序,最常用的先定義
  • 将必須使用名稱的才能使用的參數,定義為kwargs-only參數,要求必須使用關鍵字參數
  • 如果函數有很多參數,無法逐一定義,可使用可變參數,如果需要知道這些參數的意義,則使用可變關鍵字參數收集

(八)參數解構

  • 在給函數提供實參的時候,可以在疊代對下個前使用*或者**來進行結構的解構,提取出其中所有元素作為函數的實參
  • 使用*解構成位置傳參
  • 使用**解構成關鍵字傳參
  • 提取出來的元素數目要和傳參的要求比對
def add(*iterable):
    result = 0
    for x in iterable:
        result += x
    return result
add(1, 2, 3)
add(*[1, 2, 3])
add(*range(5))