1. 程式人生 > 其它 >3.21python學習筆記

3.21python學習筆記

多層裝飾器

#當需要對函式新增多個功能時,一個裝飾器無法完成,就需要用到多層裝飾器
def outter1(func1):
    print('載入了outter1')
    def wrapper1(*args, **kwargs):
        print('執行了wrapper1')
        res1 = func1(*args, **kwargs)
        return res1
    return wrapper1

def outter2(func2):
    print('載入了outter2')
    def wrapper2(*args, **kwargs):
        print('執行了wrapper2')
        res2 = func2(*args, **kwargs)
        return res2
    return wrapper2

def outter3(func3):
    print('載入了outter3')
    def wrapper3(*args, **kwargs):
        print('執行了wrapper3')
        res3 = func3(*args, **kwargs)
        return res3
    return wrapper3
@outter1
@outter2
@outter3
def index():
    print('from index')
#裝飾器的執行時從上往下的順序執行,結構性從下往上

有參裝飾器

#相當於把整個裝飾器 看成一個閉包函授,給它又包了一個函式來傳遞引數
def outer(source_data):    
    def outter1(func1):
        if source_data == '1':
            print('載入了outter1')
        def wrapper1(*args, **kwargs):
            print('執行了wrapper1')
            res1 = func1(*args, **kwargs)
            return res1
        return wrapper1
@outer('1')
def index():
    print('from index')

遞迴函式

  #遞迴就是在函式內部呼叫自己的函式被稱之為遞迴。
例項說明
1. 例1:
計算階乘  n! = 1 * 2 * 3 * ... * n, 用函式fact(n)表示, 可以看出:
fact(n) = n! = 1 * 2 * 3 * ... * (n-1) * n = (n-1)! * n = fact(n-1) * n,
所以, fact(n)可以表示為n * fact(n-1), 只有n = 1時需要特殊處理.
於是, fact(n)用遞迴的方式寫出來就是:
def fact(n):
if n == 1:
	return 1
return n * fact(n - 1)

print(fact(5))      # 輸出結果: 120
print(fact(1))      # 輸出結果: 1
"""
函式的遞迴不應該是無限迴圈的過程 真正的遞迴函式應該要滿足兩個要求
    1.每次遞迴 複雜度必須降低(下一次遞迴要比上一次遞迴解答)
        大白話 越往下遞迴應該離解決問題的答案越近
    2.必須要有明確的結束條件
"""

演算法之二分法

# 什麼是演算法?
	演算法其實就是解決問題的有效方法
  	eg:比如開啟易拉罐的問題
      	方法1:使用金屬撬棍
        方法2:直接手扣
        方法3:一陽指戳
        ...
  """
  演算法比較偏向於學術研究 很枯燥 並且產出很少
  甚至只有非常大的網際網路公司才會有演算法部分
  	演算法工程師薪資待遇很高 但是產出很少
  	有時候甚至幾年都沒有任何的成果 有點類似於研究所!!!
  """

# 演算法之二分法
	二分法是演算法裡面最入門的一個 主要是感受演算法的魅力所在
  # Author:Jason
"""二分法使用有前提: 資料集必須有先後順序(升序 降序)"""
l1 = [13,21,35,46,52,67,76,87,99,123,213,321,432,564,612]
# 查詢一個數 123
"""
二分法原理
    獲取資料集中間的元素 比對大小
        如果中間的元素大於目標資料  那麼保留資料集的左邊一半
        如果中間的元素小於目標資料  那麼保留資料集的右邊一半
    然後針對剩下的資料集再二分
        如果中間的元素大於目標資料  那麼保留資料集的左邊一半
        如果中間的元素小於目標資料  那麼保留資料集的右邊一半
    ...
"""
def get_target(l1,target_num):
    # 最後需要考慮找不到的情況 l1不可能無限制二分
    if len(l1) == 0:
        print('不好意思 真的沒有 找不到')
        return
    # 1.獲取中間元素的索引值(只能是整數)
    middle_index = len(l1) // 2
    # 2.判斷中間索引對應的資料與目標資料的大小
    if target_num > l1[middle_index]:
        # 3.保留資料集右側
        l1_left = l1[middle_index+1:]
        # 3.1.對右側繼續二分 重複執行相同程式碼 並且複雜度降低
        print(l1_left)
        get_target(l1_left,target_num)
    elif target_num < l1[middle_index]:
        # 4.保留資料集左側
        l1_right = l1[:middle_index]
        print(l1_right)
        # 4.1.對右側繼續二分 重複執行相同程式碼 並且複雜度降低
        get_target(l1_right,target_num)
    else:
        print('找到了',target_num)
# get_target(l1,432)
# get_target(l1,22)
get_target(l1,13)
"""
二分法的缺陷
    1.如果要找的元素就在資料集的開頭 二分更加複雜
    2.資料集必須有順序
目前沒有最完美的演算法 都有相應的限制條件
"""
"""
以後面試的時候  可能會讓你手用python寫一些演算法
    二分法 快排 插入 冒泡 堆排序
        上述知識面試之前臨時抱佛腳即可 平時無需過多研究
"""