1. 程式人生 > >day11-python函式基本操作

day11-python函式基本操作

1.函式

1.1定義

函式是指將一組語句的集合通過一個名字或者說模組封裝起來,要想使用這個函式,只需要呼叫其函式名稱即可。

1.2 特點

  • 減少程式碼的重複性
  • 讓程式變得可擴充套件
  • 程式容易維護

1.3 語法

def function():    # 函式關鍵字和函式名稱
    pass                    # 函式體
function() # 函式呼叫

 

2. 函式引數

2.1 實參和形參

  • 形參變數只有在被呼叫時才分配記憶體單元,在呼叫結束時,即刻釋放所分配的記憶體單元。因此,形參只在函式內部有效。函式呼叫結束返回主呼叫函式後則不能再使用該形參變數
  • 實參可以是常量、變數、表示式、函式等,無論實參是何種型別的量,在進行函式呼叫時,它們都必須有確定的值,以便把這些值傳送給形參。因此應預先用賦值,輸入等辦法使引數獲得確定值

2.2 位置實參

呼叫函式時,Python必須將函式呼叫中的每個實參都關聯到函式定義中的對應形參,因此最簡單快捷的方式是基於實參的順序。這種關聯的方式被稱為位置實參。(使用位置實參來呼叫函式時,位置一定要正確)

def test(animal,name):
    print('我有個' + animal + ',它的名字是' + name.capitalize())

test('Dog','tom'
) # 我有個Dog,它的名字是Tom

2.3 關鍵字引數

關鍵字引數是傳遞給函式的 名稱-值 對。在實參中就將名稱和值關聯起來了,從而不用考慮函式呼叫中的順序,但是在使用關鍵字引數時,必須準確的指定函式定義中的形參名稱。

PS:關鍵字引數必須在位置引數之後。

def test(animal,name):
    print('我有個' + animal + ',它的名字是' + name.capitalize())

test(name='tom',animal='Dog')
# 我有個Dog,它的名字是Tom

2.4 預設引數

這個引數在呼叫時不指定,那就預設;指定了的話,就用指定的值。

def test(animal,name = 'tom'):
    print('我有個' + animal + ',它的名字是' + name.capitalize())

test('Dog')
# 我有個Dog,它的名字是Tom
 
 

def test(animal,name = 'tom'):
    print('我有個' + animal + ',它的名字是' + name.capitalize())

test('Dog','jcak')
# 我有個Dog,它的名字是Jcak

2.5 非固定引數

若你的函式在定義時不確定使用者想傳入多少個引數,就可以使用非固定引數

def test(name, age, *args):  # *args 會把多傳入的引數變成一個元組形式
    print(name, age, args)

test("zxl", 18)
# zxl 18 () #後面這個()就是args,只是因為沒傳值,所以為空

test("wl", 32, "CN", "Python",'ee')
# wl 32 ('CN', 'Python', 'ee')

還可以有一個**kwargs

def stu(name, age, *args, **kwargs):  # *kwargs 會把多傳入的引數變成一個dict形式
    print(name, age, args, kwargs)

stu("Alex", 22)
# Alex 22 () {}#後面這個{}就是kwargs,只是因為沒傳值,所以為空

stu("Jack", 32, "CN", "Python", sex="Male", province="ShanDong")
# Jack 32 ('CN', 'Python') {'province': 'ShanDong', 'sex': 'Male'}

 

3.全域性與區域性變數

  • 在子程式中定義的變數稱為區域性變數,在程式的一開始定義的變數稱為全域性變數。
  • 全域性變數作用域是整個程式,區域性變數作用域是定義該變數的子程式。
  • 當全域性變數與區域性變數同名時:在定義區域性變數的子程式內,區域性變數起作用;在其它地方全域性變數起作用。

3.1 示例

a = 11
def test():
    a = 10
    print('函式體內:',a)

print('函式體外(呼叫函式之前):',a)
# 函式體外(呼叫函式之前): 11

test()
#函式體內: 10

print('函式體外(呼叫函式之後):',a)
#函式體外(呼叫函式之後): 11

3.2 global函式

global的作用是在函式體內建立修改全域性變數

a = 11
def test():
    global a
    a = 10
    print('函式體內:',a)

print('函式體外(呼叫函式之前):',a)
# 函式體外(呼叫函式之前): 11

test()
#函式體內: 10

print('函式體外(呼叫函式之後):',a)
#函式體外(呼叫函式之後): 10

 

4. 返回值

要想獲取函式的執行結果,就可以用return語句把結果返回,但是要注意:

  • 函式在執行過程中只要遇到return語句,就會停止執行並返回結果,so 也可以理解為 return 語句代表著函式的結束
  • 如果未在函式中指定return,那這個函式的返回值為None 

 

5.遞迴

如果一個函式在內部呼叫自身本身,這個函式就是遞迴函式。

遞迴特性:

1. 必須有一個明確的結束條件

2. 每次進入更深一層遞迴時,問題規模相比上次遞迴都應有所減少

3. 遞迴效率不高,遞迴層次過多會導致棧溢位(在計算機中,函式呼叫是通過棧(stack)這種資料結構實現的,每當進入一個函式呼叫,棧就會加一層棧幀,每當函式返回,棧就會減一層棧幀。由於棧的大小不是無限的,所以,遞迴呼叫的次數過多,會導致棧溢位)

def test(n):
    print(n)
    if int(n / 2) == 0:
        return n
    test(int(n / 2))

test(20)
# 20 10 5 2 1

 

6.匿名函式

匿名函式就是不需要顯式的指定函式名稱,本身無甚大用,但是配合其他函式使用時確實神器。。。

num = lambda w:2**w
print(num(10))

6.1 和map函式一起使用

map函式的作用是會對一個序列物件中的每一個元素進行相關操作,並且返回一個包含所有結果的map序列。

res = map(lambda x:x*2,[1,5,7,4,8])
print(type(res)) # <class 'map'>
for i in res:
    print(i)
# 2 10 14 8 16

6.2 filter函式

filter函式的作用是根據條件從序列中過濾出一些元素。

# 過濾出大於2的元素
res = filter(lambda x:x > 2,[1,5,7,4,8])
print(type(res)) # <class 'filter'>
for i in res:
    print(i)

# 5 7 4 8

6.3 reduce函式

reduce函式返回計算結果。為int型別。

from functools import reduce

res = reduce(lambda x,y:x + y,list(range(1,10)))
print(type(res),res) # <class 'int'>
for i in res:
    print(i)

# <class 'int'> 45

 

7.高階函式

變數可以指向函式,函式的引數能接收變數,那麼一個函式就可以接收另一個函式作為引數,這種函式就稱之為高階函式。

def add(x, y, f):
    return f(x) + f(y)

def foo(x):
    return x

res1 = add(3, -6, foo)
res2 = add(3, -6, abs)
print(res1,res2)
# -3 9