Python のオブジェクト指向: @property

序文

最近いくつかのソース コードを見ていると、多くのプロジェクトで Python の高度なオブジェクト指向プロパティが使用されていることがわかりました (少なくとも私はこれまでにそれらを使用したことがありません。また、私のコードはまだ低レベルすぎると感じています。そこで、ここに記録します) :

参考

@財産

私が読んだコードは次のようになります。

    @property
    def ofmap_size(self):
        """
        Get size of one output fmap.
        """
        return self.hofm * self.wofm * self.nimg

    @property
    def total_ofmap_size(self):
        """
        Get total size of all output fmaps.
        """
        return self.nofm * self.ofmap_size

これは、深層学習モデル演算子の融合を実装するコードです. これは、表現モデル層用に新しく構築されたクラスです. これら 2 つのメソッドは、主に層の出力アクティベーション サイズとすべての出力アクティベーション サイズを返します。改めてコードを見てみると、自分が書くなら絶対に @property 属性は付けないと思っていて、何をするのか分かりません。

最初の参考資料:

@property最初のリファレンスでは、クラス内のメソッドが属性で装飾されている場合、次の例のように、クラス属性を呼び出すような形式でメソッドを呼び出すことができると記載されています。

class Dog:
    def __init__(self, name, gender, age, type) -> None:
        self.name = name
        self.gender = gender
        self.age = age
        self.type = type

    @property
    def grow(self):
        age = self.age + 1
        return age

dog = Dog("xiaohei", "male", 5, "tugou")
new_age = dog.grow
print(dog.age, new_age)

結果:

5  6

grow次のように別の方法で呼び出すとnew_age = dog.grow()、次のようにエラーが報告されます。

----> 1 new_age = dog.grow()
      2 print(dog.age, new_age)

TypeError: 'int' object is not callable

つまり、ここでは元々メソッドだったgrowが属性になっています。

使用法

データでは、このメソッドを使用して Python で読み取り専用属性を返すことができることが指摘されています。Python には読み取り専用属性の実際の実装はありません。コメント エリアのコメントを借用してください:

类中定义私有属性有两种方式:一种用单下划线,表示这个属性是类的私有属性,不希望被外部访问到,但仅仅是不希望,还是可以被访问的;第二种是双下划线,表示这个属性就是类的私有属性,只能在类中被使用,不可以在实例化的对象中去使用。

纠正一下,类中 单下划线和双下划线的属性,在类外部,均可以使用实例化对象访问并且修改。区别在于:双下划线的属性名 ____FileName 被解释器重写为 _ClassName__FileName ,所以访问或者修改它的时候是 实例名._ClassName__FileName ,而单下划线的属性 _FileName,依然可以用 实例名._FileName 访问或修改

次に、次のように、上記を使用して@property読み取り専用プロパティ メソッドを実装できます。

class Dog:
    def __init__(self, name, gender, age, type) -> None:
        self.name = name
        self.gender = gender
        self._age = age
        self.type = type

    @property
    def age(self):
        return self._age

dog = Dog("xiaohei", "male", 5, "tugou")
print(dog.age)

結果:

5
dog.age += 1
print(dog.age)

結果:

AttributeError                            Traceback (most recent call last)
 in 
----> 1 dog.age += 1
      2 print(dog.age)

AttributeError: can't set attribute

この場合、ユーザーはdog.age年齢属性を直接返すことができますが、自由に変更することはできません。これは、読み取り専用プロパティの実装によく似ています。

2番目のリファレンス

上記では読み取り専用プロパティのみを実装しました。_ageプロパティが直接呼び出されない限り、プロパティを直接変更することはできません。そして、別の方法を使用してそれを変更することもできます。コードは以下のように表示されます:

class Dog:
    def __init__(self, name, gender, age, type) -> None:
        self.name = name
        self.gender = gender
        self._age = age
        self.type = type

    @property
    def age(self):
        return self._age
    
    @age.setter
    def age(self, new):
        self._age = new

dog = Dog("xiaohei", "male", 5, "tugou")
print(dog.age)
dog.age = 8
print(dog.age)

結果:

5
8

クラス内の年齢を表す実際の属性は であることがわかりますが_age、 C++ でプライベート属性を設定し、パブリック メソッドを設定してプライベート属性を操作するのdog.age同じように、それを通じてそのアクセスと変更を実現しています。_ageget_ageset_age

おすすめ

転載: blog.csdn.net/qq_43219379/article/details/130163929