ホームページ >バックエンド開発 >Python チュートリアル >Pythonデコレータとはどういう意味ですか? Python デコレータの使い方

Pythonデコレータとはどういう意味ですか? Python デコレータの使い方

PHP中文网
PHP中文网オリジナル
2017-06-20 14:30:511912ブラウズ

Python---デコレータの詳細な説明

定義:

は本質的に関数です。その機能は、別の関数 (つまり、装飾された関数) を装飾し、装飾された関数に機能を追加することです。デコレートされた関数のソースコードや呼び出し方法は変更できないことが前提となります。このような関数をデコレータと呼びます。

分析:

以下では多くを語らず、コードを使用して説明しましょう。以下は関数です。

      b=1+2

プログラム出力:

————————

3

————————

ここで、この関数に説明を追加したいと思います。次のように、デコレータを作成できます:

 1 #原函数 2 def add(): 3     a=1+2 4     print(a)  
 5 #装饰器 6 def decorator(func): 7     def warpper(): 8         print("1+2的结果是:") 9         func()10     return warpper11 #注意此句   12 add=decorator(add)13 #调用函数14 add()

プログラム出力:

——————————

1+2 の結果は次のとおりです:

3

—————— — ————

こうして、無事に目標を達成することができました。 12 行目のこの文に注目してください。この文は、add 関数オブジェクトをdecorator() 関数に渡し、変更されないことが保証されるように、新しい関数変数を add に再割り当てします。装飾された関数の呼び出しメソッドは変更されません。 Python 構文の 12 行目のステートメントを置き換える、より洗練された方法があります。以下のように:

 1  #装饰器 2 def decorator(func): 3     def warpper(): 4         print("1+2的结果是:") 5         func() 6     return warpper 7  8 #add=decorator(add) 9 #原函数10 @decorator#换成@符号11 def add():12     a=1+213     print(a)14 #调用函数15 add()

装飾された関数の直前に「@xxx」を追加します(xxxはデコレーター関数の名前です)

装飾された関数の場合はどうすればよいですかパラメーターはありますか?

装飾された関数にパラメータがある場合はどうなるでしょうか?どのように働くべきでしょうか?心配しないでください。パラメータは不定のパラメータの形式で収集できます。コード例は次のとおりです。

 1 def decorator(func): 2     def warpper(*args,**kwargs): 3         print("相加的结果是:") 4         func(*args,**kwargs) 5     return warpper 6  7 @decorator 8 def add(x,y): 9     a=x+y10     print(a)11 12 add(2,3)
程序输出:
——————————————————
相加的结果是:
5
——————————————————

以下にページ検証デコレータを記述します。

一部の Web サイトの一部のページでは、アクセスする前にユーザーがログインする必要があることは誰もが知っています。たとえば、次の 3 つの関数 (それぞれ 3 つのページを表します):

1 def index():2     print("welcome to the index page")3 def home():4     print("welcome to the home page")5 def bbs():6     print("welcome to the bbs page")7     return "I am the return contents"
ここで、ホームページとbbs ページを確認すると、ソース コードを変更するのは現時点では不可能であることがわかります。現時点では、次のようにデコレータを使用できます:

 1 username,passwd="jack","abc123"#模拟一个已登录用户 2 def decorator(func): 3     def warpper(*args,**kwargs): 4         Username=input("Username:").strip() 5         password=input("Password:").strip() 6         if username==Username and passwd==password: 7             print("Authenticate Success!") 8             func(*args,**kwargs) 9         else:10             exit("Username or password is invalid!")11     return warpper12 13 def index():14     print("welcome to the index page")15 @decorator16 def home():17     print("welcome to the home page")18 @decorator19 def bbs():20     print("welcome to the bbs page")21     return "I am the return contents"22 23 index()24 home()25 bbs()

プログラム結果:

————————

インデックスページへようこそ #インデックスでの検証なしで直接ログインできますページ

ユーザー名:jack
パスワード: abc123
認証成功!
————————

上記のコードの最後の文(25行目)を「print(bbs())」に変更して見てみると、 bbs() に戻り値があることに気付きました。彼の出力:

————————

インデックス ページへようこそ

ユーザー名:jack

パスワード:abc123

認証成功!

ホームページへようこそ

ユーザー名:jack
パスワード:abc123
認証成功! BBSページへのウェルカム
none ? ?


————————

どうしたの! bbs() の戻り値は None として出力されます。どうして?これにより、装飾された関数のソース コードが変更されませんか?これはどうすれば解決できますか?
分析してみましょう:

bbs 関数を実行すると、実際にはデコレータでラッパー関数を実行するのと同じになります。デコレータを注意深く分析すると、ラッパー関数には戻り値がないことがわかります。装飾された関数の戻り値を正しく保証できます。値が正しく返される場合は、デコレータを変更する必要があります:

1 username,passwd="jack","abc123"#模拟一个已登录用户
 2 def decorator(func): 3     def warpper(*args,**kwargs): 4         Username=input("Username:").strip() 5         password=input("Password:").strip() 6         if username==Username and passwd==password: 7             print("Authenticate Success!") 8            return func(*args,**kwargs)#在这里加一个return就行了
 9         else:10             exit("Username or password is invalid!")11     return warpper12 
13 def index():14     print("welcome to the index page")15 @decorator16 def home():17     print("welcome to the home page")18 @decorator19 def bbs():20     print("welcome to the bbs page")21     return "I am the return contents"22 
23 index()24 home()25 bbs()

如图加上第8行的return就可以解决了。下面我们在看看改后的程序输出:

————————

welcome to the index page
Username:jack
Password:abc123
Authenticate Success!
welcome to the home page
Username:jack
Password:abc123
Authenticate Success!
welcome to the bbs page
I am the return contents   #bbs()的返回值得到了正确的返回

——-——————

好了,返回值的问题解决了.

 

既然装饰器是一个函数,那装饰器可以有参数吗?

答案是肯定的。我们同样可以给装饰器加上参数。比如还是上面的三个页面函数作为例子,我们可以根据不同页面的验证方式来给程序不同的验证,而这个验证方式可以以装饰器的参数传入,这样我们就得在装饰器上在嵌套一层函数 了:

 1 username,passwd="jack","abc123"#模拟一个已登录用户 2 def decorator(auth_type): 3     def out_warpper(func): 4         def warpper(*args,**kwargs): 5             Username=input("Username:").strip() 6             password=input("Password:").strip() 7             if auth_type=="local": 8                 if username==Username and passwd==password: 9                     print("Authenticate Success!")10                     return func(*args,**kwargs)11                 else:12                     exit("Username or password is invalid!")13             elif auth_type=="unlocal":14                 print("HERE IS UNLOCAL AUTHENTICATE WAYS")15         return warpper16     return out_warpper17 18 def index():19     print("welcome to the index page")20 @decorator(auth_type="local")21 def home():22     print("welcome to the home page")23 @decorator(auth_type="unlocal")24 def bbs():25     print("welcome to the bbs page")26     return "I am the return contents"27 28 index()29 home()30 bbs()

 

输出:

————————

welcome to the index page
Username:jack
Password:abc123
Authenticate Success!
welcome to the home page
Username:jack
Password:abc123
HERE IS UNLOCAL AUTHENTICATE WAYS

————————

可见,程序分别加入了第2行和第16行和中间的根据auth_type参数的判断的相关内容后, 就解决上述问题了。对于上面的这一个三层嵌套的相关逻辑,大家可以在 pycharm里头加上断点,逐步调试,便可发现其中的道理。 

总结

要想学好迭代器就必须理解一下三条:

1.函数即变量(即函数对象的概念)

2.函数嵌套

3.函数式编程

以上がPythonデコレータとはどういう意味ですか? Python デコレータの使い方の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。