Python旅途——函式(1)

大慄發表於2019-06-20

函式

簡介

到目前為止,我們一直所接觸的都是屬於程式導向程式設計,這樣的程式碼會降低程式碼的可讀性,因此引入了函數語言程式設計,在後面我們還會學到物件導向程式設計。

函數語言程式設計

  • 函式本質:將N行程式碼拿到別處,並給他起個名字,以後通過名字就可以找到這段程式碼並執行。

  • 應用場景:程式碼重複執行,程式碼量特別多超過一屏,可以選擇函式進行程式碼的分割

物件導向程式設計

  • 對函式進行分類和封裝,讓開發“更快更好更強...”

函式基本結構:

def 函式名():
    # 函式內容
函式名() #執行函式
注:如果函式沒被呼叫,則內部程式碼永不執行

引數

1.引數的使用

  • 引數呼叫可以是任意的型別,同樣的return返回值也可以是任意型別

2.強制轉換

v1 = [1,2,3,4]
v2 = tuple(v1)

v1 = (1,2,3,4)
v2 = list(v1)

3.位置傳參(呼叫函式,並傳入引數)

def func(a,b,c):
    pass
func(1,2,3)

4. 關鍵字傳參

def func(a,b,c):
    pass
func(k1 = 1,k2 = 2,k3 = 3)
  • 位置引數和關鍵字引數可以混合使用,位置引數一定在前面,關鍵字引數一定在後面。

5. 預設引數

def func(a,b = 3):
    pass
func(11) # 可以只寫一個值,則另外一個預設就是3
func(2,3) # 也可以寫兩個值,這樣就是把2賦值給a,把3賦值給b,b不在取預設值

6. 萬能引數

  • *args :不支援關鍵字傳參,只能傳位置引數,可以接收n個位置引數,並且將引數轉化為元組

    呼叫函式無 *:

def func(*args):
    print(args)
func(1,2,3...) # 不支援關鍵字傳參,只能傳位置引數,可以接收n個位置引數,並且將引數轉化為元組

​ 呼叫函式有 *:

def func(*args):
    print(args)
func(*(1,2,3,4))
func(*[1,2,3,4])
  • **kwargs :不支援位置傳參,只能關鍵字傳參,可以接收n個關鍵字引數,並且轉化為字典

    呼叫函式無**:

def func(**kwargs):
    print(kwargs)
func(k1=1,k2=2,k3=3...) # 不支援位置傳參,只能關鍵字傳參,可以接收n個關鍵字引數,並且轉化為字典

​ 呼叫函式有**:

def func(**kwargs):
    print(kwargs)
func(**{'k1':'alex','k2':'eric'})   # kwargs={'k1':'v2','k2':'v2'}
    
  • 綜合應用 :*args + **kwargs = 無敵
def func(*args,**kwargs):
    print(*args,**kwargs)
func(1,2,3,k1=1,k2=3,k3=5)
func(*[1,2,3],k1=2,k5=9,k19=999) 
func(*[1,2,3],**{'k1':1,'k2':3}) 
func(111,222,*[1,2,3],k11='alex',**{'k1':1,'k2':3})

7. 引數相關知識重點

  • 定義函式:

    # 第一種
    def func(a,b):
        pass
    func(1,2)
    # 第二種
    def func(a,b=None):
        pass
    func(1)
    # 第三種
    def func(*args,**kwargs):
        pass
    func(1,k1=1)
  • 呼叫函式

    1. 位置引數在前
    2. 關鍵引數在後
def get_list_first_data(aaa): # aaa叫形式引數(形參)    
    v = [11,22,33,44]    
    print(v[aaa])
get_list_first_data(1) # 2/2/1呼叫函式時傳遞叫:實際引數(實參) 
練習:
# 1. 請寫一個函式,函式計算列表 info = [11,22,33,44,55] 中所有元素的和。
def value(x):
    var = 0
    for i in x:
        var += i
    print(var)
v1 = value([11,22,33,44,55])
# 2. 請寫一個函式,函式將兩個列表拼接起來。
def value(x,y):
    list1 = []
    list1.extend(x)
    list1.extend(y)
    print(list1)
value([1,2,3],['alex','eric'])
# 3. 計算一個列表的長度
def length(x):
    var = 0
    for i in x:
        var += 1
    print(var)
length([1,2,3,4,5])

返回值:

  • 函式是一個功能塊,該功能到底執行成功與否,需要通過返回值來告知呼叫者。

1.資料型別中的方法到底有沒有返回值?

  • 有返回值
  • 無返回值
  • 有返回+修改資料

2.一般常用的需要記住的:

  1. str
    • strip 返回str
    • split 返回str
    • replace 返回str
    • upper 返回str
    • lower 返回str
    • join 返回str
  2. list
    • append 無返回值
    • insert 無返回值
    • pop 返回要刪除的資料
    • remove 無返回值
    • find/index 返回索引位置
  3. dict
    • get 有返回值
    • keys 有返回值
    • values 有返回值
    • items 有返回值
  • 基本格式
def func(arg):    
    # ....    
    return 9 # 返回值為9 預設:return None
val = func('adsfadsf')
  • 下面是一些簡單的練習題來深入理解返回值的概念
# 練習
1.寫函式,計算一個列表中有多少個數字,列印: 列表中有%s個數字。 提示:type('x') == int 判斷是否是數字。
def num(list):
    var = 0
    for i in list:
        if type(i) == int:
            var += 1
    return var
v1 = num(['sdf',1,2,3,'sdf'])
print(v1)
# 2. 寫函式,計算一個列表中偶數索引位置的資料構造成另外一個列表,並返回。
def double(list):
    var = []
    for i in range(0,len(list)) :
        if i%2 == 0:
            var.append(list[i])
    return var
v1 = double([1,2,3,4,5,6])
print(v1)
# 3. 讀取檔案,將檔案的內容構造成指定格式的資料,並返回。
"""
a.log檔案
    alex|123|18
    eric|uiuf|19
    ...
目標結構:
a.  ["alex|123|18","eric|uiuf|19"] 並返回。
b. [['alex','123','18'],['eric','uiuf','19']]
c. [
   {'name':'alex','pwd':'123','age':'18'},
   {'name':'eric','pwd':'uiuf','age':'19'},
]
"""

a:
def var():
    list = []
    with open('a.log',mode='r',encoding='utf-8') as f:
        for line in f:
            list.append(line)
    return list
v1 = var()
print(v1)


b:
def var():
    list = []
    with open('a.log',mode='r',encoding='utf-8') as f:
        for line in f:
            line = line.strip()
            new_line = line.split("|")
            list.append(new_line)
    return list
v1 = var()
print(v1)


c:
def var():
    list = []
    with open('a.log',mode='r',encoding='utf-8') as f:
        for line in f:
            line = line.strip()
            new_line = line.split("|")
            a,b,c = new_line
            info = {}
            info['name'] = a
            info['pwd'] = b
            info['age'] = c
            list.append(info)
    return list
v1 = var()
print(v1)

作用域

Python中:

  1. py檔案 為全域性作用域
  2. 函式為區域性作用域
a = 1
def s1():
    x1 = 666
    print(x1)
    print(a)
    print(b)

b = 2
print(a)
s1()
a = 88888
def s2():
    print(a,b)
    s1()

s2()                        #列印結果 1,666,1,2,8888,2,666,8888,2
  • 總結:

    • 一個函式是一個作用域
    • 作用域中查詢資料規則:優先在自己的作用域中尋找,自己的作用域沒有的話,就去父級的作用域裡面找,直到找完全域性作用域
    練習題
    !/usr/bin/env python
    -*- coding:utf-8 -*-
    
    x = 10
    def func():
        x = 9
        print(x)
        def x1():
            x = 999
            print(x)
    func()
    
    x = 10
    def func():
        x = 9
        print(x)
        def x1():
            x = 999
            print(x)
        x1()
    func()     # 9,999
    
    x = 10
    def func():
        x = 9
        print(x)
        def x1():
            x = 999
            print(x)
        print(x)
        x1()
    func()     #9,9,999
    
    x = 10
    def func():
        x = 8
        print(x)
        def x1():
            x = 999
            print(x)
        x1()
        print(x)
    func()   #8,999,8
    
    
    x = 10
    def func():
        x = 8
        print(x)
        def x1():
            print(x)
        x1()
        print(x)
    func()      # 8,8,8
    
    
    
    x = 10
    def func():
        x = 8
        print(x)
        def x1():
            print(x)
        x = 9
        x1()
        x = 10
        print(x)
    func()     # 8,9,10
    
    
    x = 10
    def func():
        x = 8
        print(x)
        def x1():
            print(x)
    
        x1()
        x = 9
        x1()
        x = 10
        print(x)
    func()   #  8,8,9,10-
    • 子作用域中只能找到父級中的值,預設無法重新為父級的變數重新賦值
    name = 'dali'
    def func():
        name = 'alex' # 在自己作用域再建立一個這樣的值。
        print(name)
    func()
    print(name)
    
    # #####################
    name = [1,2,43]
    def func():
        name.append(999)
        print(name)
    func()
    print(name)
    
    # ###################### 如果非要對全域性的變數進行賦值
    # 示例一
    name = ["大慄",'alex']
    def func():
        global name
        name = '我'
    func()
    print(name)
    # 示例一
    name = "大慄"
    def func():
        name = 'alex'
        def inner():
            global name
            name = 999
        inner()
        print(name)
    func()
    print(name)
    
    # #####################
    name = "大慄"
    def func():
        name = 'alex'
        def inner():
            global name
            name = 999
        inner()
        print(name)
    func()
    print(name)
    # #####################
    name = "大慄"
    def func():
        name = 'alex'
        def inner():
            nonlocal name # 找到上一級的name
            name = 999
        inner()
        print(name)
    func()
    print(name)
    
    • 重新賦值
      1. global:找到全域性變數並可以對它進行重新賦值
      2. nonlocal:找到上一級的變數,並對它進行修改
  • 以後全域性變數都要大寫,區域性可以小寫

總結

主要對於函式的引數、返回值、以及函式的作用域做了簡單的介紹和分享。

相關文章