Python のデコレーターは、Python に入るハードルです。越えるか越えないかに関係なく、ハードルは存在します。 Python のデコレーターの概念は人々を混乱させることが多いので、今日は Python のデコレーターを分析しましょう
1 スコープ
Python には、グローバル スコープとローカル スコープの 2 種類のスコープがあります。
グローバル スコープは、ファイル レベルで定義された変数と関数の名前です。ローカル スコープは 定義関数 内にあります。
スコープに関しては、次の 2 つの点を理解する必要があります: a. ローカルに定義された変数はグローバルにアクセスできませんが、グローバルに定義された変数は変更できません (もちろん、変更する方法はあります)。
次の例を見てみましょう:x = 1 def funx(): x = 10 print(x) # 打印出10 funx() print(x) # 打印出1
定義された変数 x がローカルに存在しない場合、関数は x を内側から外側に検索します。それが見つからない場合は、エラーが報告されます。
x = 1 def funx(): print(x) # 打印出1 funx() print(x) # 打印出1 x = 1 def funx(): def func1(): print(x) # 打印出1 func1() funx() print(x) # 打印出1スコープの問題に関しては、次の 2 つの点だけを覚えておく必要があります。グローバル変数はファイル内のどこでも参照できますが、変更は必要な変数がローカルに見つからない場合にのみグローバルに実行できます。見つからない場合は、外部で検索され、エラーが報告されます。
2. 高度な関数
関数名は実際にはメモリ空間のアドレスを指していることがわかっているので、この機能を使用できます。 a.関数名を値として使用できますdef delete(ps): import os filename = ps[-1] delelemetns = ps[1] with open(filename, encoding='utf-8') as f_read,\ open('tmp.txt', 'w', encoding='utf-8') as f_write: for line in iter(f_read.readline, ''): if line != '\n': # 处理非空行 if delelemetns in line: line = line.replace(delelemetns,'') f_write.write(line) os.remove(filename) os.rename('tmp.txt',filename) def add(ps): filename = ps[-1] addelemetns = ps[1] with open(filename, 'a', encoding='utf-8') as fp: fp.write("\n", addelemetns) def modify(ps): import os filename = ps[-1] modify_elemetns = ps[1] with open(filename, encoding='utf-8') as f_read, \ open('tmp.txt', 'w', encoding='utf-8') as f_write: for line in iter(f_read.readline, ''): if line != '\n': # 处理非空行 if modify_elemetns in line: line = line.replace(modify_elemetns, '') f_write.write(line) os.remove(filename) os.rename('tmp.txt', filename) def search(cmd): filename = cmd[-1] pattern = cmd[1] with open(filename, 'r', encoding="utf-8") as f: for line in f: if pattern in line: print(line, end="") else: print("没有找到") dic_func ={'delete': delete, 'add': add, 'modify': modify, 'search': search} while True: inp = input("请输入您要进行的操作:").strip() if not inp: continue cmd_1 = inp.split() cmd = cmd_1[0] if cmd in dic_func: dic_func[cmd](cmd_1) else: print("Error")b.関数名を戻り値として使用できます
def outer(): def inner(): pass return inner s = outer() print(s) ######输出结果为####### <function outer.<locals>.inner at 0x000000D22D8AB8C8>c..関数名をパラメータとして使用できます
def index(): print("index func") def outer(index): s = index s() outer(index) ######输出结果######### index func以上の 2 つの条件が満たされています。 どれでも高レベル関数と呼ぶことができます。
3. クロージャ関数
クロージャ関数は、次の 2 つの条件を満たす必要があります。 1. 関数内で定義された関数 2.グローバル スコープではなく外部スコープが含まれます。 以下は、いくつかの例を通じてクロージャ関数への参照です: 例 1: 以下は関数内で関数を定義するだけですが、これはクロージャ関数ではありませんdef outer(): def inner(): print("inner func excuted") inner() # 调用执行inner()函数 print("outer func excuted") outer() # 调用执行outer函数 ####输出结果为########## inner func excuted outer func excuted
例2: 以下は関数 A 関数内で定義されており、外部変数も参照しています。 2 番目の項目が満たされていないことがわかったはずです。はい、ここでの変数 x はグローバル変数であり、外部に作用する変数ではありません。ドメイン。次の例を見てみましょう:
x = 1 def outer(): def inner(): print("x=%s" %x) # 引用了一个非inner函数内部的变量 print("inner func excuted") inner() # 执行inner函数 print("outer func excuted") outer() #####输出结果######## x=1 inner func excuted outer func excuted
明らかに、上記の例はクロージャー関数の条件を満たしています。ここで、クロージャ関数として、上記の 2 つの条件を満たさなければならず、どちらも削除できないことを知っておく必要があります。ただし、通常の状況では、クロージャ関数に値を返します。その理由についてはここでは説明しません。次のコンテンツで、この戻り値の使用方法を説明します。
def outer(): x = 1 def inner(): print("x=%s" %x) print("inner func excuted") inner() print("outer func excuted") outer() #####输出结果######### x=1 inner func excuted outer func excuted
次に、クロージャを定義します。関数。これは、関数とそれに関連する参照環境で構成されるエンティティです。深い制約を実装する場合、参照環境を明示的に表すものを作成し、それを関連するサブルーチンとバンドルして、バンドルがクロージャになるようにする必要があります。上記の例では、クロージャ関数が実際にクロージャ関数と呼ばれるには、それ自体の関数と外部変数が含まれている必要があることがわかります。外部変数がバインドされていない場合、関数はクロージャー関数とみなされません。
def outer(): x = 1 def inner(): print("x=%s" %x) print("inner func excuted") print("outer func excuted") return inner # 返回内部函数名 outer()結果は、内部で 2 つの外部ローカル変数が参照されていることを示しています。非ローカル変数が参照されている場合、ここでの出力は None になります。 クロージャ関数の特徴: 1. 独自のスコープが付いています 2. 遅延計算
それでは、クロージャ関数が何をするのかは明らかです。 , クロージャー関数を定義する場合は、外部環境にバインドする必要があります。この全体をクロージャー関数とみなすことができ、このバインディング機能を使用して特定の特殊な関数を完成させることができます。
例3:受信したURLに従ってページのソースコードをダウンロードする
def outer(): x = 1 y = 2 def inner(): print("x= %s" %x) print("y= %s" %y) print(inner.closure) return inner outer() ######输出结果####### (<cell at 0x000000DF9EA965B8: int object at 0x000000006FC2B440>, <cell at 0x000000DF9EA965E8: int object at 0x000000006FC2B460>)これはクロージャ関数の条件を満たしていないという人もいるかもしれませんが、非グローバル外部変数を参照していません。実際、前に述べたように、関数内の変数が関数に属している限り、これは当てはまりません。次に、index(url) に移動します。この URL も関数内に属しますが、手順が 1 つ省略されているため、上記の関数はクロージャ関数でもあります。
4. デコレータ
上記の基礎により、デコレータを簡単に理解できます。
デコレータ: 外部関数は装飾された関数の名前を渡し、内部関数は装飾された関数の名前を返します。
特徴: 1. 装飾された関数の呼び出しメソッドを変更しません 2. 装飾された関数のソースコードを変更しません a. パラメーターのないデコレーター
以下の例では、コードの実行時間を計算する必要があります。
import time, random def index(): time.sleep(random.randrange(1, 5)) print("welcome to index page")
根据装饰器的特点,我们不能对index()进行任何修改,而且调用方式也不能变。这时候,我们就可以使用装饰器来完成如上功能.
import time, random def outer(func): # 将index的地址传递给func def inner(): start_time = time.time() func() # fun = index 即func保存了外部index函数的地址 end_time = time.time() print("运行时间为%s"%(end_time - start_time)) return inner # 返回inner的地址 def index(): time.sleep(random.randrange(1, 5)) print("welcome to index page") index = outer(index) # 这里返回的是inner的地址,并重新赋值给index index()
但是,有些情况,被装饰的函数需要传递参数进去,有些函数又不需要参数,那么如何来处理这种变参数函数呢?下面来看看有参数装饰器的使用情况.
b.有参装饰器
def outer(func): # 将index的地址传递给func def inner(*args, **kwargs): start_time = time.time() func(*args, **kwargs) # fun = index 即func保存了外部index函数的地址 end_time = time.time() print("运行时间为%s"%(end_time - start_time)) return inner # 返回inner的地址
下面来说说一些其他情况的实例。
如果被装饰的函数有返回值
def timmer(func): def wrapper(*args,**kwargs): start_time = time.time() res=func(*args,**kwargs) #res来接收home函数的返回值 stop_time=time.time() print('run time is %s' %(stop_time-start_time)) return res return wrapper def home(name): time.sleep(random.randrange(1,3)) print('welecome to %s HOME page' %name) return 123123123123123123123123123123123123123123
这里补充一点,加入我们要执行被装饰后的函数,那么应该是如下调用方式:
home = timmer(home) # 等式右边返回的是wrapper的内存地址,再将其赋值给home,这里的home不在是原来的的那个函数,而是被装饰以后的函数了。像home = timmer(home)这样的写法,python给我们提供了一个便捷的方式------语法糖@.以后我们再要在被装饰的函数之前写上@timmer,它的效果就和home = timmer(home)是一样的。
如果一个函数被多个装饰器装饰,那么执行顺序是怎样的。
import time import random def timmer(func): def wrapper(): start_time = time.time() func() stop_time=time.time() print('run time is %s' %(stop_time-start_time)) return wrapper def auth(func): def deco(): name=input('name: ') password=input('password: ') if name == 'egon' and password == '123': print('login successful') func() #wrapper() else: print('login err') return deco @auth # index = auth(timmer(index)) @timmer # index = timmer(index) def index(): time.sleep(3) print('welecome to index page') index()
实验结果表明,多个装饰器装饰一个函数,其执行顺序是从下往上。
关于装饰器,还有一些高级用法,有兴趣的可以自己研究研究。
以上がPython デコレータの詳細なサンプル チュートリアルの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

PythonとCにはそれぞれ独自の利点があり、選択はプロジェクトの要件に基づいている必要があります。 1)Pythonは、簡潔な構文と動的タイピングのため、迅速な開発とデータ処理に適しています。 2)Cは、静的なタイピングと手動メモリ管理により、高性能およびシステムプログラミングに適しています。

PythonまたはCの選択は、プロジェクトの要件に依存します。1)迅速な開発、データ処理、およびプロトタイプ設計が必要な場合は、Pythonを選択します。 2)高性能、低レイテンシ、および緊密なハードウェアコントロールが必要な場合は、Cを選択します。

毎日2時間のPython学習を投資することで、プログラミングスキルを効果的に改善できます。 1.新しい知識を学ぶ:ドキュメントを読むか、チュートリアルを見る。 2。練習:コードと完全な演習を書きます。 3。レビュー:学んだコンテンツを統合します。 4。プロジェクトの実践:実際のプロジェクトで学んだことを適用します。このような構造化された学習計画は、Pythonを体系的にマスターし、キャリア目標を達成するのに役立ちます。

2時間以内にPythonを効率的に学習する方法は次のとおりです。1。基本的な知識を確認し、Pythonのインストールと基本的な構文に精通していることを確認します。 2。変数、リスト、関数など、Pythonのコア概念を理解します。 3.例を使用して、基本的および高度な使用をマスターします。 4.一般的なエラーとデバッグテクニックを学習します。 5.リストの概念を使用したり、PEP8スタイルガイドに従ったりするなど、パフォーマンスの最適化とベストプラクティスを適用します。

Pythonは初心者やデータサイエンスに適しており、Cはシステムプログラミングとゲーム開発に適しています。 1. Pythonはシンプルで使いやすく、データサイエンスやWeb開発に適しています。 2.Cは、ゲーム開発とシステムプログラミングに適した、高性能と制御を提供します。選択は、プロジェクトのニーズと個人的な関心に基づいている必要があります。

Pythonはデータサイエンスと迅速な発展により適していますが、Cは高性能およびシステムプログラミングにより適しています。 1. Python構文は簡潔で学習しやすく、データ処理と科学的コンピューティングに適しています。 2.Cには複雑な構文がありますが、優れたパフォーマンスがあり、ゲーム開発とシステムプログラミングでよく使用されます。

Pythonを学ぶために1日2時間投資することは可能です。 1.新しい知識を学ぶ:リストや辞書など、1時間で新しい概念を学びます。 2。練習と練習:1時間を使用して、小さなプログラムを書くなどのプログラミング演習を実行します。合理的な計画と忍耐力を通じて、Pythonのコアコンセプトを短時間で習得できます。

Pythonは学習と使用が簡単ですが、Cはより強力ですが複雑です。 1。Python構文は簡潔で初心者に適しています。動的なタイピングと自動メモリ管理により、使いやすくなりますが、ランタイムエラーを引き起こす可能性があります。 2.Cは、高性能アプリケーションに適した低レベルの制御と高度な機能を提供しますが、学習しきい値が高く、手動メモリとタイプの安全管理が必要です。


ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

Video Face Swap
完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

人気の記事

ホットツール

MantisBT
Mantis は、製品の欠陥追跡を支援するために設計された、導入が簡単な Web ベースの欠陥追跡ツールです。 PHP、MySQL、Web サーバーが必要です。デモおよびホスティング サービスをチェックしてください。

EditPlus 中国語クラック版
サイズが小さく、構文の強調表示、コード プロンプト機能はサポートされていません

ZendStudio 13.5.1 Mac
強力な PHP 統合開発環境

Safe Exam Browser
Safe Exam Browser は、オンライン試験を安全に受験するための安全なブラウザ環境です。このソフトウェアは、あらゆるコンピュータを安全なワークステーションに変えます。あらゆるユーティリティへのアクセスを制御し、学生が無許可のリソースを使用するのを防ぎます。

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)
