[PY3]——Python的函式

Jelly_lyj發表於2017-03-18

Python函式總結圖

  

1.呼叫

1.1 如何呼叫

   1.1.1  函式名(傳參)

# 函式使用函式名來呼叫,函式名後緊跟一對小括號,小括號裡傳入函式定義時要求的引數
add(9,9)
#9+9=18

 

1.2 傳參

   1.2.1  傳參方法1:位置引數

   1.2.2  傳參方法2:關鍵字引數

def add(x,y):
    ret=x+y
    print('{}+{}={}'.format(x,y,ret))
    return ret

# 傳參方法1:位置引數  指引數按照定義的順序傳入
add(8,9)
#8+9=17

# 傳參方法2:關鍵字引數  指引數按照定義時的變數名傳入
add(x=9,y=8)
#9+8=17

# 規則1:位置引數和關鍵字引數可以混合使用
add(3,y=9)
#3+9=12

# 規則2:但混合使用時,位置引數必須在前面,否則SyntaxError
add(x=3,9) #SyntaxError: positional argument follows keyword argument # 注意1: add('3','9') #3+9=39 # 注意2:傳入引數必須和函式定義時的引數相匹配,如果不匹配會丟擲TypeError add(9,9,9) #TypeError: add() takes 2 positional arguments but 3 were given

 

1.3 引數解構

   1.3.1  位置引數解構:*可迭代物件

   1.3.2  關鍵字引數解構:*字典

iter=[3,9]
add(iter[0],iter[1])
#3+9=12

# 位置引數解構:*可迭代物件  可以把可迭代物件解構成位置引數
add(*iter)
#3+9=12
add(*range(2))
#0+1=1

# 關鍵字引數解構:*字典   可以把字典解構成關鍵字引數
# 關鍵字引數解構,key必須是str
dict={'x':3,'y':9}
add(**dict)
#3+9=12

 

2. 函式定義

2.1 如何定義

   def 函式名(引數列表):
                   執行語句
                   return 返回值

def add(x, y):     # 函式定義 def 表示定義一個函式;緊接著是函式名,函式名後面用一對小括號列出引數列表;引數列表後面使用一個冒號開始函式體
    print(x + y)   # 函式體是正常的Python語句,可以包含任意結構
    return  x + y  # return語句表示函式的返回值

 

2.2 函式的引數

   2.2.1  普通引數

   2.2.2  預設引數

   2.2.3  可變引數(*變數  **變數)

   2.2.4  keyword-only引數

   2.2.5  引數設定規則

# 可以為引數設定預設值,呼叫時如果不傳遞此引數,會使用預設值
def inc(x,y=9):
    print(x+y)

inc(1,10)
#11

inc(1)
#10
# 位置可變引數:*變數  構成元祖,以位置引數的形式傳參
def sum(*lst):
    print(type(lst))
    ret=0
    for x in lst:
        ret+=x
    print(ret)

sum(1,2,3,4,5)
#<class 'tuple'>
#15
sum(1,2,3)
#<class 'tuple'>
#6

# 關鍵字可變引數:**變數  構成字典,以關鍵字引數的形式傳參
def connect(**kwargs):
    print(type(kwargs))
    for k,v in kwargs.items():
        print('{}——>{}'.format(k,v))

connect(host='127.0.0.1',port=3306)
#<class 'dict'>
#host——>127.0.0.1
#port——>3306

# 所以如果要建立一個接受任意型別引數的函式,可以如何定義?
def wrap(*args,**kwargs)
# 規則1:普通引數和可變引數可以一起使用,但傳參必須匹配
def fn(x,y,*args,**kwargs):
    print("x=",x)
    print("y=",y)
    print("args=",args)
    print("kwargs=",kwargs)

fn(1,2)
#x= 1
#y= 2
#args= ()
#kwargs= {}

fn(1,2,0,2,6,a=3,b=9)
#x= 1
#y= 2
#args= (0, 2, 6)
#kwargs= {'b': 9, 'a': 3}

fn(2,y=3)
#x= 2
#y= 3
#args= ()
#kwargs= {}

fn(2,3,6,9,x=1)
#TypeError: fn() got multiple values for argument 'x'


# 規則2:位置可變引數如果放普通引數之前,普通引數會變成keyword-only引數
def fn(*args,x):
     pass
fn(2,3,0)
#TypeError: fn() missing 1 required keyword-only argument: 'x'


# 規則3:而關鍵字可變引數就不能在普通引數|預設引數之前
def fn(**kwargs,x):
     pass
#SyntaxError: invalid syntax

def fn(**kwargs,x=9):
    pass
#SyntaxError: invalid syntax

# 規則4:不建議可變引數和預設引數一起使用 def fn(*args,x=5): print(args) print(x) fn(1,2,3) #(1, 2, 3) #5 def fn(x=5,*args): print(x) print(args) fn(1,2,2) #1 #(2, 2) # 規則5:位置可變引數和關鍵字可變引數可以同時使用,但位置可變引數必須在前面 def fn(*args,**kwargs): print(args) print(kwargs) fn(1,2,3,a=3,b=9) #(1, 2, 3) #{'a': 3, 'b': 9} def fn(**kwargs,*args,): pass #SyntaxError: invalid syntax

 

3. 函式返回值

# 返回值除了返回值的作用外,還會結束函式,return後的語句將不會被執行
# 所以有結束函式作用的需求時,可以直接寫“return”即可
def add(x,y):
    return x+y
    print("test")

print(add(3,9))
#12

# 一個函式可以有多個return,執行到哪個就由哪個返回並結束 def guess(x): if x>3: return '>3' print('end') return '<=3' print('end') print(guess(3)) #<=3 print(guess(9)) #>3
# return可以提前結束迴圈 # 沒有return返回None def fn(x): for i in range(x): if i>=3: return i else: print('not bigger than 3') print(fn(10)) #3 #not bigger than 3 print(fn(2)) #None # return多個值時,可以用封裝把返回值封裝成一個元組、用解構來獲取 def fn(): return 3,5 print(type(fn())) #<class 'tuple'> x,y=fn() print(x,y) #3 5

 

4.函式作用域

4.1 上下級作用域的變數的關係

# 函式內部是一個區域性作用域,對上級作用域(全域性作用域)的變數x ——>只讀可見,不可操作
x=1
def inc():
     x+=1
inc()
#UnboundLocalError: local variable 'x' referenced before assignment

def inc():
     print(x)
inc()
#1
def fn():
     xx=1
     print(xx)
     def inner():
         print(xx)   #上級作用域的變數對下級作用域是可見的
     inner()
fn()
#1
#1

def fn():
     xx=1
     print(xx)
     def inner():
         xx=2      #在inner()作用域內定義的變數,那就只對該內部作用域及其下級作用域可見
         print(xx)
     inner()
     print(xx)
fn()
#1
#2
#1

4.2 global 標記全域性變數

#global 全域性變數
xx=2
def fn():
     global xx  #將上級作用域的xx變數標記為全域性變數
     xx+=1      #則可對它操作了
fn()
print(xx)
#3

def fn():
   global aa=1    #注意global只能標記,並不能定義變數
   aa+=1
fn()
#SyntaxError: invalid syntax

#除非你清楚的知道global會帶來什麼,並且明確的知道,非global不行, 否則不要使用global

4.3 nonlocal 

def fn():
     xx=1
     print(xx)
     def inner():
          xx+=1   #對上級作用域定義的xx,原本是不可操作或定義的
          print(xx)
     inner()
fn()
#UnboundLocalError: local variable 'xx' referenced before assignment


def fn():
    xx=1
    print(xx)
    def inner():
        nonlocal xx  #nonlocal可以標記上一級作用域變數,使它可讀可寫
        xx+=1
        print(xx)
    inner()
fn()
#1
#2

 

5. 匿名函式(lambda)

5.1 lambda 可以怎樣被定義和使用

lambda x:x+1
#<function __main__.<lambda>>

print((lambda x:x+1)(5))
#6

f=lambda x:x+1
print(f(5))
#6

# 匿名函式(lambda表示式) 只能寫在一行上所以也有人叫它單行函式
f=lambda x: if x <0:
        0
    else:
        0
#SyntaxError: invalid syntax

5.2 lambda支援所有的引數列表及規則

# 匿名函式支援所有普通函式所支援的引數列表及規則
print((lambda :0)())
#0

print((lambda x,y:x+y)(3,5))
#8

print((lambda *args:args)(*range(3)))
#(0, 1, 2)

print((lambda *args,**kwargs:print(args,kwargs))(*range(3),**{str(x):x for x in range(3)}))
#(0, 1, 2) {'0': 0, '2': 2, '1': 1}

5.3 lamdba常和sorted( )等高階函式一起使用

# 匿名函式通常用於高階函式的引數,當此函式非常短小的時候,就適合使用匿名函式

 

6. 生成器函式(yield)

def gen():
    print('a')
    yield 1
    print('b')
    yield 2
    return 3

g=gen()

print(g)
#<generator object gen at 0x7f144845a308>

print(next(g))
#a
#1

print(next(g))
#b
#2

print(next(g))
#StopIteration: 3

# 帶yield語句的函式稱之為生成器函式, 生成器函式的返回值是生成器 
* 生成器函式執行的時候,不會執行函式體

* 當next生成器的時候, 當前程式碼執行到之後的第一個yield,會彈出值,並且暫停函式

* 當再次next生成器的時候,從上次暫停處開始往下執行

* 當沒有多餘的yield的時候,會丟擲StopIteration異常,異常的value是函式的返回值

更多關於生成器參考:《[PY3]——函式——生成器(yield關鍵字)》

 

7. 函式執行流程

相關文章