1. 程式人生 > >Python基礎筆記_Day08_Python偏函式、回撥函式、遞迴函式

Python基礎筆記_Day08_Python偏函式、回撥函式、遞迴函式

Day08_Python偏函式、回撥函式、遞迴函式

08.01_Python語言基礎(偏函式)(熟練)
08.02_Python語言基礎(回撥函式)(掌握)
08.03_Python語言基礎變數(Python變數)(重點重點重點掌握)
08.04_Python語言基礎(遞迴函式)(重點)
08.05_Python語言基礎(棧模擬遞迴遍歷目錄)(熟練)
08.06_Python語言基礎(佇列模擬遍歷目錄)(熟練)

08.01_Python語言基礎(偏函式)(熟練)

定義:
* 函式在執行時,要帶上所有必須的引數進行呼叫,但是有時引數可以在函式被呼叫之前提前獲知
* 好處: 一個函式或者多個函式的引數預先就能用上,一邊函式能用更少的引數進行呼叫

from functools import partial


def add(a, b):
    return a + b


add(3, 5)   # 8
add(4, 7)   # 11

puls = partial(add, 100)
result = puls(10)
print(result)

執行輸出結果:

110

# 進位制轉換
import functools

# 案例:
print(int("1010", base=2), "--> base表示進位制")


# 偏函式
def int2(str, base=2):  # int(x,base)x-->字串或者數字  base---》進位制數   預設是十進位制
    return int(str, base)


print(int2("1011"))
int3 = functools.partial(int, base=2)
print(int3("111"))

總結:
在這裡偏函式表示式的意思就是:
* 在函式add的呼叫時,我們已經知道里面其中一個引數,我們通過這個引數,
* 重新繫結一個函式partial(add,100),然後再去呼叫

08.02_Python語言基礎(回撥函式)(掌握)

回撥函式的定義

  • 回撥函式:
    • 就是通過函式指標呼叫函式,如果你把函式的指標(地址)作為引數傳遞給另外一個函式,當這個指標被用來呼叫其所指向的函式時,------回撥函式,
    • 回撥函式不是由該函式的實現方直接呼叫,而是在特定的事件或者條件發生時由另外一方呼叫,用於對該時間或者條件進行響應

回撥函式使用案例


第一個案例(回撥函式無返回值):

def clear1(times):
    """
    模擬賓館掃地
    :param times:
    :return: None
    """
    print("完成掃地的次數", str(times))


def clear2(times):
    """
    模擬賓館灑水
    :param times:
    :return: None
    """
    print("灑水的次數", str(times))


def call_clear(times, function_name):
    """
    相當於控制器,控制方法的呼叫,實現回撥函式的核心
    :param times:   呼叫函式次數
    :param function_name: 回撥函式名稱
    :return: 呼叫函式的結果
    """
    return function_name(times)


call_clear(10, clear1)

第二個案例(回撥函式有返回值):

"""
回撥函式
1.編寫生成一個2 * K形式偶數的函式
2.編寫一個數字字串轉換為數字(base=2)形式的函式
"""


def double_2k(x):
    return x * 2


def str2int02(x):
    return int(x, base=2)


def get_result(func, num):
    return func(num)


print(get_result(str2int02, "1001"))
print(get_result(double_2k, 23))

08.03_Python語言基礎變數(Python變數)(重點重點重點掌握)

變數的分類
* 區域性變數
* 成員變數(全域性變數)

區域性變數

#區域性變數
def test1():
    a = 10
    b = 10
    
def test2():
    a = 10
    b = 20
    
# 以上函式中的變數----》區域性變數

總結:
區域性變數:
    就是在函式內部定義的變數
    不同的函式,可以定義相同名字的區域性變數,各個變數之間不會發生干涉不會影響
    區域性變數的作用:為了臨時儲存資料需要在函式中定義變數來進行儲存

全域性變數

#全域性變數

定義:
   如果一個變數,既能在一個函式中使用,
 也能在另外一個函式中使用---》全域性變數
"""
#定義一個全域性變數
a = 100
def test3():
    print(a)
def test4():
    print(a)

test3()
test4()

全域性變數和區域性變數名字相同的問題

"""
全域性變數和區域性變數名字相同的問題
"""  
s = 100
def test5():
    s = 200
    print(s)
    s = 300
    print(s)
    
def test6():
    print(s)
test5()

修改全域性變數

* global  關鍵字   修改全域性變數

* 格式:global 需要修改變數名  

# 沒有加global修飾的全域性變數
num = 11
def num01():
    num = 12
    return num
print(num01())
print(num)
print("*" * 30)

# 在外部加global修飾的全域性變數
global num001
num001 = 110
def num011():
    global num001
    num001 = 100
    return num001
print(num011())
print(num001)
print("*" * 30)

# 在函式內部加global修飾的全域性變數
num002 = 110
def num012():
    global num002
    num002 = 100
    return num002
print(num012())
print(num002)
print("*" * 30)

再來一個案例

print("*" * 30)

wendu = 0
def get_wendu():
    # 想一下wendu=33不加註釋的執行結果
    # wendu = 33
    global wendu
    wendu = 34

def print_wendu():
    print(wendu)

get_wendu()
print_wendu()

區域性變數和全域性變數的區別

1.在函式外面定義的變數稱為:全域性變數
2.全域性變數能夠在所有的函式中被訪問
3.如果在函式中修改全域性變數,那麼需要使用global關鍵字進行宣告,否則出錯
4.如果出現同名的現象,先到區域性找---》全域性-----》報錯,這個被稱為:就近原則

他們的本質的區別:
     在於作用域

區域性變數和全域性變數區別案例

#案例:
def get_wendu():
    wendu = 33
    return wendu
def print_wendu(wendu):
    print(wendu)
    
result = get_wendu()
print_wendu(result)

wendu = 0
def get_wendu1():
    wendu = 34
    # global wendu
    wendu = 33
    
def print_wendu1():
    print(wendu)

可變型別的全域性變數

  • 可變型別值: 列表 字典 集合
  • 不可變型別: 引用 元祖 數字 字串

當不可變的資料型別作為全域性變數: 需要用global宣告,進行修改
當可變的資料型別作為全域性變數:  不一定需要global宣告

可變型別的全域性變數案例:

#案例:
test = []
def d():
    test.append(2)
    print(test)
d()

test1 = []
def e():
    test1 = [1,2]
    # global test1
    test1 = [3,4]
    # print(test1)
e()
print(test1)

test2 = [1,2]
def f(a):
    a += a
    print(a)

f(test2)
print(test2)

再來一個案例

# 沒有加global修飾的全域性變數--可變型別
list01 = [1, 2, 3, 4]
def list001():
    list01.append(5)
    return list01
print(list001())
print(list01)
print("*" * 30)

# 加global修飾的全域性變數--可變型別
global list02
list02 = [6, 1, 2, 3, 4]
def list002():
    global list02
    list02.append(5)
    return list02
print(list002())
print(list02)

不可變型別的全域性變數案例:

#不可變
a = 1
def g():
    a = 2
    a += 1
    print(a)
    # global a
    a = 4
g()
print(a)

08.04_Python語言基礎(遞迴函式)(重點)

遞迴函式的定義

定義:
    在函式中不呼叫其他函式,而是呼叫自己------》遞迴函式(自己玩自己)
    凡是迴圈能做的事,遞迴都能做  

遞迴函式的作用

def show():
    print("我叫王二小")
    show()
show()


"""    
例如:

   計算一個階乘n!
   n! = 1*2*3*4...*n
   1! = 1
   2! = 2*1 2*1!
   3! = 3*2*1 3*2!
   4! = 4*3*2*1 4*3!
   n! = n*(n-1)!
   
   引數
       要   1個   
   返回值
       要   結果    

#方法1
def calnum(num):
    # for temp in range(1,num+1):
    i = 1
    result = 1
    while i <= num:
        # result = result * i
        result *= i
        i += 1
    return result
ret = calnum(3)
print(ret)

#方法2:
def calnum(num):
    if num >=1:
        result = num*calnum(num-1)
    else:
        result = 1
    return result
ret = calnum(3)
print(ret)

注意:防止死迴圈(遞迴)

遞迴遍歷目錄

import os
 
def getAllDirRE(path,sp = ""):
    #得到當前目錄下的所有的檔案
    filesList = os.listdir(path)
    #處理每一個檔案
    sp += "  "
    for fileName in filesList:
        #判斷是否是路徑(用絕對路徑)
        fileAbsPath = os.path.join(path,fileName)
        if os.path.isdir(fileAbsPath):

            print(sp+"目錄:",fileName)
            #遞迴函式
            getAllDirRE(fileAbsPath,sp)
        else:
            print(sp + "普通檔案",fileName)
getAllDirRE(r"G:\1806")

08.05_Python語言基礎(棧模擬遞迴遍歷目錄)(熟練)

  • 模擬棧儲存方式獲取指定路徑下所有檔案

棧定義:
    又名堆疊,
import os
"""
棧:
    先進後出
    裝子彈
"""
#模擬棧結構
#入棧
stack = []
stack.append("A")
print(stack)
stack.append("B")
print(stack)
stack.append("C")
print(stack)

#出棧
res1 = stack.pop()
print("res1=",res1)
print(stack)
res2 = stack.pop()
print("res1=",res2)
print(stack)

def getAllDirRE(path):
    stack = []
    stack.append(path)
    #處理棧,當棧為空的時候結束當前動作
    while len(stack) != 0:
        #從棧中取資料
        dirPath = stack.pop()
        filesList = os.listdir(dirPath)
        #得到的資料,如果是普通的檔案,直接列印,如果,是目錄繼續壓棧
        for fileName in filesList:
            fileAbsPath = os.path.join(dirPath,fileName)
            if os.path.isdir(fileAbsPath):
                print("目錄"+fileName)
                #壓棧
                stack.append(fileAbsPath)
            else:
                print("普通"+fileName)
getAllDirRE(r"G:\1806")

08.06_Python語言基礎(佇列模擬遍歷目錄)(熟練)

  • 模擬佇列獲取指定路徑下所有檔案

"""
先進先出   排隊
collections
append:新增
queue:獲取佇列
len:獲取長度
popleft:出隊

listdir:獲取當前目錄的所有檔案
isdir  :判斷是否是檔案

"""
import os
import collections

def getAllDirQu(path):
    #建立一個佇列
    queue = collections.deque()
    #進隊
    queue.append(path)
    while len(queue) != 0:
        #出隊
        dirPath = queue.popleft()
        #獲取當前路徑下的所有的檔案
        filesList = os.listdir(dirPath)

        for fileName in filesList:
            #絕對路徑
            fileAbsPath = os.path.join(dirPath,fileName)
            #判斷是否是目錄(資料夾),如果是進隊,不是直接列印
            if os.path.isdir(fileAbsPath):
                print("目錄:"+fileName)
                queue.append(fileAbsPath)
            else:
                print("普通檔案"+fileName)

getAllDirQu(r"G:\1806")