1. 程式人生 > >python學習筆記12(裝飾器、偏函式、變數作用域)

python學習筆記12(裝飾器、偏函式、變數作用域)

裝飾器、偏函式、變數作用域

裝飾器
定義: 是一個閉包,把一個函式當做引數,返回一個替代版的函式
本質: 就是一個返回函式的函式
示例:

#簡單的裝飾器
def func1():    #定義了一個函式
    print("sunck is a good man")

#希望在不改變上面函式的情況下,給函式新增別的功能
#定義一個簡單的裝飾器
def outer(func):     #輸入的是一個函式
    def inner():      #在inner函式中給輸入的函式新增功能
        print("*******************")   #要新增的功能
        func()    #輸入的函式的功能
    return inner     #返回innner函式
#f是函式func1的加強版本
f = outer(func1)    #f等於inner函式
f()    #執行inner函式
   # outer(func1)()        #等價於上面的兩個語句
   # 輸出:
*******************
sunck is a good man

使用@符號將裝飾器應用到函式

def outer(func):
    def inner(age):
        if age < 0:
            age = 0
        func(age)
    return inner
#say = outer(say)      #@outer   #相當於say = outer(say)
@outer 
def say(age):
    print("sunck is %d years old" % (age))
say(-10)

#輸出:
sunck is 0 years old

裝飾器常用於對某些已有的函式進行修飾,使其滿足特定的需求
通用裝飾器:

def outer(func):
    def inner(*args, **kwargs):   #使傳入的引數符合所有型別
        #新增修改的功能
        print("&&&&&&&&&&&&&")
        func(*args, **kwargs)
    return inner

@outer #say = outer(say)
def say(name, age): #函式的引數力理論上是無限制的,但實際上最好不要超過6、7個
    print("my name is %s, I am %d years old" % (name, age))
    
say("sunck", 18)
#輸出:
&&&&&&&&&&&&&
my name is sunck, I am 18 years old

偏函式: 對函式的預設值進行修改的函式、理論上不需要人為定義
示例:
#int預設是10進位制,即base=10,把base改成2

print(int("1010"))
#輸出:1010
print(int("1010", base = 2))
#輸出:10
#偏函式,該函式把int函式預設base改成2
def int2(str, base = 2):
    return int(str, base)
print(int2("1011"))

import functools
#把一個引數固定住,形成一個新的函式
int3 = functools.partial(int, base = 2)      #用functools模組生成偏函式
print(int3("111"))

變數作用域
作用域: 變數可以使用的範圍。程式的變數並不是在所有位置都能使用的,訪問的許可權決定於變數的在哪裡賦值的
作用域分類:
區域性作用域
函式作用域(閉包以外的函式)
全域性作用域:在定義到整片文件結束之間使用
內建作用域
在這裡插入圖片描述
示例:

num = 10
print(id(num))    #輸出:1447652656
def func():
    #宣告num為全域性變數,方便在函式中修改
    global num
    # 修改num
    num = 20
    print(id(num))       #輸出:1447652976  
    #可以使用,但是無法直接修改
    #num = 20#相當於在函式內部定義了一個num
    #可以直接使用外部全域性變數的的值
    print("num =", num)      #輸出:num = 20

func()
print("外部列印num =", num)    #輸出:外部列印num = 20
print(id(num))     #輸出:1447652976

區域性-》函式-》全域性-》內建
python中只有模組、函式、類才會引入新的的作用域去,其他的(if/if-elif-else/while/for)等不會引入新的作用域的
示例:

if 1:
    a = 10
print(a)    #輸出:10
#體現作用域
def func():
    b = 20
    print("b =", b)
func()
#print(b)  #報錯,因為b找不到

def outer():
    num = 10
    def inner():
        nonlocal num      #num為非區域性變數
        num = 20
        def little():
            nonlocal num
            num = 30
            print("在little裡列印Num =", num)
        little()
        print("在inner裡列印num =", num)
    inner()
    print("在outer裡列印num =", num)
outer()
#輸出:
在little裡列印Num = 30
在inner裡列印num = 30
在outer裡列印num = 30


def outer():
    num = 10
    def inner():
        num = 20
        def little():
            nonlocal num
            num = 30
            print("在little裡列印Num =", num)
        little()
        print("在inner裡列印num =", num)
    inner()
    print("在outer裡列印num =", num)
outer()

#輸出:
在little裡列印Num = 30
在inner裡列印num = 30
在outer裡列印num = 10