簡體   English   中英

Python - 裝飾器

[英]Python - Decorators

我正在嘗試學習Decorators 我理解了它的概念,現在正在嘗試實現它。

這是我編寫的代碼 代碼是不言自明的。 它只是檢查參數是否傳入int

def wrapper(func):
    def inner():
        if issubclass(x,int): pass
        else: return 'invalid values'

    return inner()

@wrapper
def add(x,y):
    return x+y

print add('a',2)

它拋出錯誤,說global name 'x' is not defined 我知道它沒有在inner下定義,但不知道如何糾正這段代碼? 我哪里錯了?

你的裝飾器應該是這樣的:

def wrapper(func):
    def inner(x, y): # inner function needs parameters
        if issubclass(type(x), int): # maybe you looked for isinstance?
            return func(x, y) # call the wrapped function
        else: 
            return 'invalid values'
    return inner # return the inner function (don't call it)

需要注意的幾點:

  • issubclass需要一個類作為第一個參數(你可以用一個簡單的 try/except TypeError 替換它)。
  • 包裝器應該返回一個函數,而不是被調用函數的結果
  • 您實際上應該在內部函數中調用包裝函數
  • 你的內部函數沒有參數

你可以在這里找到關於裝飾器的很好的解釋。

我看到您當前的代碼存在三個問題。

首先,您調用的是inner函數,而不是返回對它的引用。

其次,您的inner函數不采用與您正在裝飾的函數相同的參數。 在這種情況下,您至少需要明確地采用x參數(某些內部函數可以專門使用*args**kwargs ,但顯然不是您的)。

最后,您永遠不會調用包裝函數。 雖然這不是嚴格要求的(在開發過程中用裝飾器替換方法可能很有用),但通常您希望在內部函數代碼期間的某個時刻調用該函數。

所以,為了把整個事情包裝在一起,我認為你希望你的代碼是這樣的:

def wrapper(func):
    def inner(x, y):
        if issubclass(x, int): # issue 2
            return func(x, y) # issue 3
        else:
            return "invalid values" # consider raising an exception here instead!

    return inner # issue 1

這可能有效。

def wrapper(func):
    def inner(*args,**kwargs):
        if ((args[0] is int) and (args[1] is int)): pass
        else: return 'invalid values'
    return inner
@wrapper
def add(x,y):
    return x+y
print add('a',2)

如果您想在類型檢查失敗時正確終止 add 方法,您也可以引發異常。 像這樣

def check_int_types(func):
    def type_checker(x, y):
        if issubclass(type(x), int) and issubclass(type(y), int):
            return func(x, y)
        raise Exception("Invalid types: {}, {}".format(x, y))
    return type_checker

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

def main():
    x = y = 15.0
    print add(x, y)

if __name__ == '__main__':
    main()

結果:

Traceback (most recent call last):
  File "deco_test.py", line 17, in <module>
    main()
  File "deco_test.py", line 14, in main
    print add(x, y)
  File "deco_test.py", line 5, in type_checker
    raise Exception("Invalid types: {}, {}".format(x, y))
Exception: Invalid types: 15.0, 15.0

這怎么辦。

def wrapper(func):
    def inner():
        if isinstance(func,int):
                return func(x, y)
        else: return 'invalid values'

    return inner()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM