Python マジック関数の学習 __missing__

WBOY
リリース: 2022-03-14 10:14:37
オリジナル
2363 人が閲覧しました

この記事では、python に関する関連知識を提供します。主に「__missing__()」関数の関連問題を紹介します。皆さんのお役に立つことを願って、この魔法の関数を一緒に見てみましょう。

Python マジック関数の学習 __missing__

# 推奨学習:

Python 学習チュートリアル

1. やや貴重な __missing__()

通常の辞書から値をフェッチする場合、キーが存在しない可能性があります:

#

dd = {'name':'PythonCat'}
dd.get('age')        # 结果:None
dd.get('age', 18)    # 结果:18
dd['age']            # 报错 KeyError
dd.__getitem__('age')  # 等同于 dd['age']
ログイン後にコピー

Python マジック関数の学習 __missing__get() メソッドの場合、戻り値があり、2 番目のパラメータを取得できます。キーが存在しない場合は戻り内容として渡されるため、許容されます。ただし、他の 2 つの書き込み方法ではエラーが報告されます。

後者の 2 つの記述方法の問題を解決するには、__missing__() マジック メソッドを使用できます。

ここで、次のようなリクエストがあるとします。辞書から特定のキーに対応する値を取得し、値があればその値を返し、値がなければキーを挿入し、それにデフォルト値 (空のリストなど)。

ネイティブ dict を使用する場合、実装は簡単ではありませんが、Python には非常に使いやすい拡張クラス

collections.defaultdict

:

が用意されています。

Python マジック関数の学習 __missing__図に示すように、存在しないキーを取得する場合、KeyError は再度報告されませんが、デフォルトで辞書に格納されます。

defaultdict でこれができるのはなぜですか?

その理由は、defaultdict は組み込み型 dict を継承した後に __missing__() メソッドも定義しているためです。__getitem__ が存在しない値を受け取ると、入力パラメーターで渡されたファクトリ関数が呼び出されます。上の例では list() を呼び出して空のリストを作成します)。

最も典型的な例として、defaultdict はドキュメントのコメントに次のように記述します。

Python マジック関数の学習 __missing__ つまり、

__missing__() のメイン関数は次によって呼び出されます。 KeyError を避けるためにキーが欠落している場合は __getitem__ を使用します。

もう 1 つの典型的な使用例は

collections.Counter

で、これも dict のサブクラスです。カウントされていないキーをフェッチすると、カウント 0 が返されます。

Python マジック関数の学習 __missing__2. とらえどころのない __missing__()

上記からわかるように、__getitem__() が値を取得できない場合には __missing__() が呼び出されます。詳細:

__getitem__() は、値を取得できない場合に必ずしも __missing__() を呼び出すわけではありません。

これは、組み込み型の必須属性ではなく、辞書基本クラスで事前定義されていないためです。

属性値を dict 型から直接取得すると、属性が存在しないことが報告されます:

AttributeError: type object 'object' has noattribute '__missing__'

dir() を使用して、この属性が存在しないことを確認します。

Python マジック関数の学習 __missing__オブジェクトである dict の親クラスから確認すると、同じ結果が得られます。 ######どうしたの? dict と object の両方に __missing__ 属性がないのはなぜですか?

ただし、最新の公式ドキュメントを確認すると、オブジェクトには明らかに次の属性が含まれています:

出典: https://docs.python.org/3/ リファレンス/datamodel.html?highlight=__missing__#object.__missing__

Python マジック関数の学習 __missing__言い換えると、理論的には __missing__ はオブジェクト クラスで事前定義されており、そのドキュメントはこれを証明していますが、実際には定義されていません。書類と現実には齟齬がある!

このように、dict のサブクラス (defaultdict や Counter など) が __missing__ を定義している場合、このマジック メソッドは実際にはそのサブクラスにのみ属する、つまり

Magic で生まれたメソッドです。サブクラスのメソッド!

これに基づいて、私は未熟な推測を持っています: __getitem__() は、現在のオブジェクトが dict のサブクラスであるかどうか、および __missing__() があるかどうかを判断してから、それを呼び出します (このメソッドもは親クラスに存在するため、最初に判断されず、直接呼び出されます)。 私はコミュニケーション グループでこの推測について言及しましたが、一部の学生はすぐに CPython ソース コードで検証を見つけました:

そしてこれは興味深いものです。 組み込み型のサブクラスにのみ存在するマジック メソッド。 Python の世界全体を見渡しても、おそらく 2 番目の例を見つけるのは難しいでしょう。

ふと思ったのですが、このとらえどころのない __missing__() は、「人を生き物に変える」のが得意な魔術師のようです。まず、観客に外のガラス越しに彼を見てもらいます(つまり、役人)ただし、ドアが開いたとき、彼は中にいません (つまり、組み込み型)。小道具を変更すると、再び元の状態で表示されます (つまり、dict のサブクラス)。

3. __missing__()

__missing__() の魔法は、「魔法」そのものに加えて、強力な「魔法」「才能主導」も必要であるということです。

前回の記事で、ネイティブ マジック メソッドが互いに独立していることがわかりました。C 言語インターフェイスでは同じコア ロジックを持つ可能性がありますが、Python 言語インターフェイスでは呼び出し関係がありません。

Python マジック関数の学習 __missing__

マジック メソッドのこの種の「通信なし」動作は、一般的なコード再利用原則に違反しており、また、組み込み型のサブクラスでいくつかの奇妙な動作を引き起こします。

公式 Python は、マジック メソッドを再利用するよりも、新しい UserString、UserList、および UserDict サブクラスを提供することを希望します。唯一の合理的な説明は、マジック メソッドを相互に呼び出すコストが高すぎるということのようです。

ただし、特殊なケース __missing__() の場合、Python は妥協し、この代償を支払わなければなりません。

__missing__() は、マジック メソッドの「第二級市民 」です。独立した呼び出し入り口がなく、__getitem__()、つまり __missing__() によって受動的に呼び出すことしかできません。 __getitem__() に依存します。

__init__()、__enter__()、__len__()、__eq__() などの「第一級国民 」とは異なり、オブジェクトの寿命に属します。サイクルまたは実行 プロセス内の特定のノードがトリガーされるか、組み込み関数または演算子によってトリガーされます。これらは比較的独立したイベントであり、依存関係はありません。

__missing__() はメソッド呼び出しを実現するために __getitem__() に依存し、完全な機能を実現するために __getitem__() も __missing__() に依存します。

これを実現するために、__getitem__() はインタープリター コードでバックドアを開き、C 言語インターフェイスから Python インターフェイスに戻り、「__missing__」という名前の特定のメソッドを呼び出します。

Python マジック関数の学習 __missing__

そして、これが本当の「魔法」です。今のところ、このような扱いが受けられる魔法のメソッドは __missing__() だけのようです。

4. 概要

Python の辞書には、値を取得するための 2 つの組み込みメソッド、つまり __getitem__() と get() が用意されています。値が存在しない場合、それらの処理戦略は異なります。 ##前者はエラー KeyError を報告し、後者は None を返します。

なぜ Python には 2 つの異なるメソッドが用意されているのでしょうか?あるいは、なぜ Python がこれら 2 つのメソッドを異なる方法で処理するのかを尋ねる必要があります。

これには非常に複雑な (または非常に単純な) 説明が必要になる場合がありますが、この記事では詳しく説明しません。

しかし、1 つ確かなことは、ネイティブ dict 型で単純かつ大雑把に

KeyError をスローする方法では不十分であるということです。

辞書型により強力なパフォーマンスを与える (または __getitem__() を get() のように動作させる) ために、Python では辞書のサブクラスが __getitem__() 呼び出しの __missing__() を定義できるようにします。

この記事では、__missing__() の実装原理を徹底的に調べ、それが目立たない存在ではないことを明らかにしています。それどころか、

これは、マジック メソッド間の障壁を打ち破り、次のような方法での使用をサポートする唯一のものです。その他のマジック メソッド マジック メソッド呼び出しの特殊なケース!

マジック メソッドの独立性を維持するために、Python は UserString、UserList、UserDict などの派生クラスを導入することに多大な労力を費やしましたが、__missing__() については妥協することを選択しました。

推奨学習:

Python チュートリアル

以上がPython マジック関数の学習 __missing__の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:csdn.net
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!