ホームページ > バックエンド開発 > Python チュートリアル > Python 記述子の使用法の概要 (例付き)

Python 記述子の使用法の概要 (例付き)

不言
リリース: 2019-03-16 09:44:55
転載
2505 人が閲覧しました

この記事では、Python 記述子の使用法を (例とともに) 紹介します。これは一定の参考価値があります。必要な友人は参照できます。お役に立てば幸いです。

あなたは Python ユーザーとして、しばらく Python を使用しているかもしれませんが、Python で記述子を使用したことはないかもしれません。次は記述子の使い方の紹介です。

シーンの紹介

記述子の使用を導入するために、最初に非常に単純なクラスを設計します。

class Product():

    def __init__(self,name,quantity,price):
        self.name = name
        self.quantity = quantity
        self.price = price
ログイン後にコピー

これは、商品の名前、数量、および価格を格納する商品クラスです。

製品の場合、通常、その数量と価格がマイナスにならないことが期待されます。この状況を回避するために、初期化中に次のような判断を追加できます:

class Product():

    def __init__(self,name,quantity,price):
        self.name = name
        if quantity<0:
            raise ValueError(&#39;quantity must be >= 0&#39;)
        self.quantity = quantity
        if quantity<0:
            raise ValueError(&#39;price must be >= 0&#39;)
        self.price = price
ログイン後にコピー

ただし、この判断は初期化中にのみ追加され、クラス インスタンスに属性を割り当てるときに、割り当てられた値が 0

## よりも大きいという保証はまだないという欠点もあります。この問題を解決するための機能:

class Product():

    def __init__(self,name,quantity,price):
        self.name = name
        self.quantity = quantity
        self.price = price

    @property
    def quantity(self):
        return self._quantity

    @quantity.setter
    def quantity(self,value):
        if value < 0:
            raise ValueError(&#39;quantity must be >= 0&#39;)
        else:
            self._quantity = value

    @property
    def price(self):
        return self._price

    @price.setter
    def price(self, value):
        if value < 0:
            raise ValueError(&#39;price must be >= 0&#39;)
        else:
            self._price = value

book = Product(&#39;mybook&#39;,6,30)
print(book.quantity)
ログイン後にコピー

ここでの @property と @quantity.setter は 2 つのデコレータであり、プロパティの読み取りと書き込みを設定できますが、実際にはこれはプロパティの読み取りと書き込みと同等です。関数を実行します。機能の具体的な紹介については、自分で調べることができます。ここでの主な目的は、記述子を引き出すことです。

属性を使用すると、属性に値を割り当てるときに判断を追加できます。しかし、クラス内にさらに多くの属性があり、多くの属性で非負の代入のチェックを追加する必要がある場合、属性の使用は非常に面倒になり、コードの重複が多くなり、多くのデコレータが追加されることになります。記述子を使用してこの問題を解決できます。

ディスクリプタの使用

最初にディスクリプタの概念を見てみましょう

ディスクリプタは「バインディング動作」のオブジェクト属性であり、ディスクリプタ プロトコルではメソッド フィルを渡すことができます。プロパティへのアクセス。これらのメソッドには、get()、set()、および delete() が含まれます。これらのメソッドのいずれかがオブジェクトで定義されている場合、そのオブジェクトは記述子

(これらのメソッドは特別なメソッドであり、二重です。下線は異なります)変換により表示されます)

まず、記述子の使用に従って上記の製品クラスを変更します。

class NotNegative():
    def __init__(self,name):
        self.name = name

    def __set__(self, instance, value):
        if value < 0:
            raise ValueError(self.name+&#39; must be >= 0&#39;)
        else:
            instance.__dict__[self.name] = value

class Product():
    quantity = NotNegative(&#39;quantity&#39;)
    price = NotNegative(&#39;price&#39;)

    def __init__(self,name,quantity,price):
        self.name = name
        self.quantity = quantity
        self.price = price

book = Product(&#39;mybook&#39;,2,5)
ログイン後にコピー

NotNegative は記述子クラスであり、Product クラスのクラス属性です。

この例では、book.quantity=3 が実行されると、インタープリターは最初にインスタンス属性を検索し、数量属性があることを検出しますが、インタープリターは記述子であるクラス属性も存在することも検出します。したがって、インタプリタは最終的にこのパスに対して Descriptor を選択することになります。すると、ディスクリプタなので、ディスクリプタに設定されている特別なメソッドが実行されます。

ディスクリプタに設定された特殊メソッドのパラメータは

self: ディスクリプタのインスタンスです

instance: インスタンス book に相当します

##例では #value: 割り当てられる値です。

これらの属性には値に対する特別な要件がないため、この例では get 特別メソッドは実装されていません。

get メソッドには、self、instance、owner の 3 つのパラメータもあります。 self、instance は set のものと同じで、owner は例の Product クラスです。

次に、主に記述子の set メソッド

instance.__dict__[self.name] = value
ログイン後にコピー
# の else 部分で実行される操作を見ていきます。 ## book インスタンスの dict を呼び出すことで、dict 内の属性に値を直接割り当てます。これは、パラメーターでインスタンスを渡す重要な理由でもあります。記述子オブジェクトはクラス属性として存在するため、このクラスのオブジェクトが多数アクセスされる可能性があるため、属性の上書きを防ぐために、インスタンスの属性に直接格納することが適切です。ただし、ここでは属性に値を割り当てる方法はありません。そうしないと、無限ループに陥ってしまいます。

データ記述子と非データ記述子の場合、クラスが get() メソッドのみを定義し、set()、delete() メソッドを定義していない場合、そのクラスは非データ記述子とみなされます。それ以外の場合は、データ記述子。

最後に、この記事では記述子の使用方法を簡単に紹介して説明します。さらに詳しく理解する必要がある場合は、「Smooth Python」の属性記述子のセクションを参照してください。

以上がPython 記述子の使用法の概要 (例付き)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:cnblogs.com
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート