序文
最近いくつかのソース コードを見ていると、多くのプロジェクトで 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
同じように、それを通じてそのアクセスと変更を実現しています。_age
get_age
set_age