Python---python函式學習總結

maidu_xbd發表於2020-10-09

目錄

 

函式

定義函式

匿名函式

高階函式

函式變數作用域: LEGB 原則

裝飾器


函式

在一個完整的專案中,某些功能會反覆的使用,會產生很多重複的程式碼。將重複使用的程式碼封裝成函式,當我們要使用此功能時呼叫即可。這樣可以複用程式碼,增加程式碼的可維護性。

定義函式

以 def 關鍵詞開頭,後接函式識別符號名稱和圓括號()。

任何傳入引數和自變數必須放在圓括號中間。圓括號之間可以用於定義引數。

return [表示式] 結束函式,選擇性地返回一個值給呼叫方。不帶表示式的return相當於返回 None

def func(*args,**kv):

...

return ret_val

import math
def get_area(r, h):  # 計算圓柱的面積
    area = math.pi*r**2*h
    return area

print(get_area(5, 10))  # 輸出785.3981633974483

函式引數

引數順序基本原則:位置引數,預設引數,可變長位置引數,可變長關鍵字引數

  • 位置引數:呼叫函式時根據函式定義的引數位置來傳遞引數。
  • 預設引數:呼叫函式時,預設引數的值如果沒有傳入,則被認為是預設值。
  • 關鍵字引數:通過“鍵=值”形式加以指定。可以讓函式更加清晰、容易使用,同時也清除了引數的順序需求。使用關鍵字引數允許函式呼叫時引數的順序與宣告時不一致,因為 Python 直譯器能夠用引數名匹配引數值。
  • 可變長位置引數*args:加了星號(*)的變數名會存放所有未命名的變數引數。
  • 可變長關鍵字引數**kwargs

*和**,也可以在函式呼叫的時候使用,稱之為解包裹(unpacking)​​​​​​​

注意:所有位置引數必須出現在預設引數前,包括函式定義和呼叫。有位置引數時,位置引數必須在關鍵字引數的前面,但關鍵字引數之間不存在先後順序的。

函式返回值

  • 單返回值
  • 多返回值:元組
def record_test(str="hello"):
    print(str)

record_test()  # 使用預設引數hello 輸出hello
record_test(str="world")  # 關鍵字引數 輸出world
# 函式引數:預設引數,可變引數
def record_info(name, age, *args, **kwargs):
    print(name, age)  # 位置引數 輸出Tom 13
    print(args)  # 可變長位置引數 輸出(190, 32)
    print(kwargs)  # 可變長關鍵字引數 輸出{'city': 'shenzhen', 'isMale': False}


record_info("Tom", 13, 190, 32, city="shenzhen", isMale=False)

 函式的引數可接受另外一個函式,返回值也可以返回另外一個函式。

def foo():
    print("foo")


def ff(func):
    print("ff")
    return func


ret_func = ff(foo)  # 輸出ff
ret_func()  # 輸出foo

匿名函式

  • 形式:lambda
  • lambda最好不要用於複雜的邏輯,可讀性不好
  • lambda表示式中的輸入引數是一個自由變數
  • 在執行時邦定值,而不是定義時就繫結:如果想讓某個匿名函式在定義時就捕獲到值,可以將那個引數值定義成預設引數。
# 匿名函式
lambda x: int(x)

# 上面的匿名函式等價於


def ret_int(item):
    return int(item)


num_list = [1, "99", "77", 38]
num_list.sort(key=lambda x: int(x))
print(num_list)  # 輸出[1, 38, '77', '99']

高階函式

1、map()

map() 會根據提供的函式對指定序列做對映。

第一個引數 function 以引數序列中的每一個元素呼叫 function 函式,返回包含每次 function 函式返回值的新列表。

map_obj = map(lambda x: x**2, [10, 20, 30])
# 輸出<map object at 0x0000000002880A58> [100, 400, 900]
print(map_obj, list(map_obj))

2、reduce()

reduce() 函式會對引數序列中元素進行累積。

函式將一個資料集合(連結串列,元組等)中的所有資料進行下列操作:用傳給 reduce 中的函式 function(有兩個引數)先對集合中的第 1、2 個元素進行操作,得到的結果再與第三個資料用 function 函式運算,最後得到一個結果。

import functools
sum = functools.reduce(lambda x, y: x+y, [1, 4, 5, 6])
print(sum)  # 輸出16

3、filter()

filter() 函式用於過濾序列,過濾掉不符合條件的元素,返回由符合條件元素組成的新列表。

該接收兩個引數,第一個為函式,第二個為序列,序列的每個元素作為引數傳遞給函式進行判斷,然後返回 True 或 False,最後將返回 True 的元素放到新列表中。

filter_obj = filter(lambda x: x % 2 == 0, [2, 4, 3, 2, 5, 3, 9, 7])
# 輸出<filter object at 0x0000000002880A90> [2, 4, 2]
print(filter_obj, list(filter_obj))

函式變數作用域: LEGB 原則

locals(本地作用域)->enclosing function(閉包)->globals(全域性作用域)->builtins(內建作用域)
當在函式中使用未確定的變數名時,Python 搜尋 4 個作用域:本地作用域(L),之後是上一層巢狀結構中 def 或 lambda 的本地作用域(E),之後是全域性作用域(G),最後是內建作用域(B)。按LEGB原則查詢到則停止。如果沒有找到則報錯。

裝飾器

一個裝飾器就是一個函式,它接受一個函式作為引數並返回一個新的函式。

裝飾器函式在被裝飾的函式定義後立即執行。被裝飾的函式只有在明確呼叫時才執行。

普通裝飾器:

# 普通裝飾器
def decorate(func):
    print("decorate is running!")

    def inner():
        print("====inner===")
        # 返回的函式被替換了
    return inner


@decorate
def foo():
    print("==foo==")
    # foo()函式定義後執行裝飾器decorate函式,輸出decorate is running!


foo()  #被裝飾的函式只有在明確呼叫時才執行 輸出====inner===, # 返回的函式被替換了

帶引數的裝飾器

import time

def record_time(func):
    def inner(*args, **kwargs):
        start_time = time.time()
        func(*args, **kwargs)
        end_time = time.time()
        print("%s函式執行了%f秒" % (func.__name__, end_time-start_time))
    return inner


@record_time
def foo1():
    print("foo1")

foo1()  # 輸出foo1   foo1函式執行了0.000500秒

def decorator1(func):
    def inner(*args):
        func(*args)  # foo2 (10, 30, 'mm')
        print("====decorator===", args)  # ====decorator=== (10, 30, 'mm')
    return inner

@decorator1
def foo2(*args):
    print("foo2", args)

foo2(10, 30, "mm")  # 輸出foo2 (10, 30, 'mm')    ====decorator=== (10, 30, 'mm')
import time


def record_time(func):
    def inner(*args, **kwargs):
        start_time = time.time()
        func(*args, **kwargs)
        end_time = time.time()
        print("%s函式執行了%f秒" % (func.__name__, end_time-start_time))
    return inner


@record_time
def foo1():
    print("foo1")


foo1()  # 輸出foo1   foo1函式執行了0.000500秒


def decorator1(func):
    def inner(*args):
        func(*args)
        print("====decorator===", args)
    return inner


@decorator1
def foo2(a):
    print("foo2")


foo2(10) #輸出foo2     ====decorator=== (10,)

參考:https://www.runoob.com/python/python-tutorial.html

相關文章