生活不止眼前的苟且
阿新 • • 發佈:2018-12-20
裝飾器
函式裡面定義函式 (函式裡面可以定義類)
def foo():
def bar(): #3
print('in bar()') #4
print('in foo()') #1
bar() #2
foo()
#結果
in foo()
in bar()
為什麼要在函式裡面定義函式呢?有啥特別之處? 函式裡面函式的有效範圍是在foo()函式裡面的, 其實定義在裡面的函式,在外面還是有辦法訪問的,可以吧函式變數弄到外面去,通過返回值
def foo(): def bar(): print('in bar()') print('in foo()') return bar #這裡的bar對應的是bar()這個函式的變數,是沒有括號的 #foo()() #也可以把下面兩行註釋掉,直接foo()(),因為foo()返回的是bar, inner = foo() #foo的返回值賦值給一個變數,inner對應的是一個函式物件 inner() #inner()和bar(),是同一樣的函式
裝飾器
定義類的靜態方法時,就使用了裝飾器 @staticmethod #靜態方法不需要self,例項方法要self。因為他不需要訪問不同的例項的屬性。 #靜態方法不能訪問例項屬性,但是可以訪問靜態屬性
def jump():
print("3 meters high")
裝飾器的特點是用一個@開頭的字串 在我們閱讀別人的程式碼時,會經常碰到裝飾器 裝飾器通常用來裝飾函式 裝飾器主要用來給函式增加一點功能 一般裝飾器本身也是一個函式 我們可以想象成它包含了被裝飾的函式
例子:
def hello(): return "hello" def hi(): return "hi"
*我們需要返回值多兩個感嘆號
def endsign(func): def wrapper(): return func() + "!!" return wrapper @endsign #裝飾器,裝飾hello的,裝飾器本身是一個函式,或是類的方法。@endsign等價於執行了hello = endsign(hello)這行程式碼。 def hello(): return "hello" #hello = endsign(hello) #等號的右邊,賦值給左邊,hello是endsign()函式的返回值 print(hello())
#上面的等價於這個
def endsign(func): #5
def wrapper(): #6
return func() + ' !!' #7 一個函式裡包含了外部物件,叫閉包
return wrapper #hello hello對應的是hello()這個函式的變數
@endsign #寫他的效果和註釋的哪行效果一樣的
def hello(): #2
return 'hello' #3
#hello = endsign(hello) #4 endsign(hello)的返回值賦給變數
print(hello()) #1
#結果
hello!!
用裝飾器一般開發的是庫 有時候要裝飾的函式還沒有寫呢
有引數的的函式 有引數的的函式 要裝飾的函式的引數還不一樣???該怎麼辦? 可以用可變引數的方法
def endsign(func):
def wrapper(*args,**kargs): #可變引數*args時元組,關鍵字可變引數**kargs是字典
print('args:',args)
print('kargs:',kargs)
return func(*args,**kargs) + ' !!' #func(*args,**kargs)這種方法,不管被裝飾的函式,原來是怎麼呼叫的,後來就怎麼傳給他
return wrapper
@endsign #被修飾了之後,呼叫hello,就是呼叫wrapper
def hello(arg1,arg2=''):
print('arg1:',arg1)
print('arg2:',arg2)
return 'hello %s %s' % (arg1,arg2)
# hello = endsign(hello)
@endsign
def goodbye(targets):
return 'goodbye %s ' % ' '.join(targets)
# print(hello('cat', 'dog'))
# print('=====================\n')
print(hello('cat', arg2='dog'))
# print('=====================\n')
print(goodbye(['jack', 'lisa', 'tom', 'mike']))
有引數的函式 裝飾器本身有引數 比如,hello後面,加!!或??等
def endsign(func):
def wrapper(*args,**kargs): #可變引數*args時元組,關鍵字可變引數**kargs是字典
print('args:',args)
print('kargs:',kargs)
return func(*args,**kargs) + ' !!' #func(*args,**kargs)這種方法,不管被裝飾的函式,原來是怎麼呼叫的,後來就怎麼傳給他
return wrapper
@endsign #被修飾了之後,呼叫hello,就是呼叫wrapper
def hello(arg1,arg2=''):
print('arg1:',arg1)
print('arg2:',arg2)
return 'hello %s %s' % (arg1,arg2)
# hello = endsign(hello)
@endsign
def goodbye(targets):
return 'goodbye %s ' % ' '.join(targets)
# print(hello('cat', 'dog'))
# print('=====================\n')
print(hello('cat', arg2='dog'))
# print('=====================\n')
print(goodbye(['jack', 'lisa', 'tom', 'mike']))