Pythonの管理属性
8954 ワード
いくつかの内容を勉強します. __getattr__および_setattr__メソッドは、未定義のプロパティ取得とすべてのプロパティ付与値を汎用プロセッサメソッド に向ける. __getattribute__メソッドは、すべての属性をPython 3に向ける.0クラスの1つの汎用プロセッサの方法 propertyは関数を内蔵し、特定の属性アクセスをgetとset処理関数に位置決めし、特性(Property) とも呼ばれる.記述子プロトコルは、特定の属性アクセスを任意のgetおよびsetプロセッサメソッドを有するクラスのインスタンス に位置決めする.
プロパティ・プロトコルを使用すると、特定のプロパティのgetおよびset操作を、プロパティ・アクセス時にコードを自動的に実行できるように、提供された関数またはメソッドに指定できます.
*基礎知識
attribute=property(fget,fset,fdel,doc)の4つのパラメータは、属性attributeのget,set,delメソッド、ドキュメント情報をそれぞれ表します.
すべてのクラスプロパティと同様に、インスタンスと下位のサブクラスはプロパティを継承します.
計算プロパティ
装飾を使用してプロパティを記述する
ディスクリプタ
記述子は、属性アクセスをブロックする代替方法を提供します.プロパティは記述子の一種であり、property内蔵関数は特定のタイプの記述子を作成する簡略化された方法である.ディスクリプタプロトコルを使用すると、プロパティに特定のプロパティのgetおよびset操作を、プロパティにアクセスするときに自動的に実行されるコードを挿入する方法を提供し、プロパティの削除をブロックし、プロパティにドキュメントを提供することができます.記述子は独立したクラスとして作成され、メソッド関数のようにクラス属性に割り当てられます.また、サブクラスとインスタンスで*の基礎知識を継承することもできます.
これらのメソッドを持つクラスは記述子と見なすことができ、あるインスタンスが別のクラスのプロパティに割り当てられた場合、これらのメソッドは特殊です.プロパティにアクセスすると自動的に呼び出されます.記述子パラメータ:記述子クラスインスタンス(self)と記述子インスタンスに追加されたクライアントクラスのインスタンス(instance)が渡されます.get__アクセスメソッドはまた、記述子インスタンスが追加するクラスを指定するownerパラメータを追加的に受信します.
記述子の計算プロパティ
ディスクリプタでのステータス情報の使用ディスクリプタ状態ディスクリプタ動作のための内部データを管理するための .インスタンスのステータスには、クライアントクラスに関する情報と、クライアントクラスが作成する可能性のある情報 が記録されている.
記述子クラスの属性ではなく、顧客クラスに添付されたインスタンスを格納または使用する属性です.
__getattr__および_getattribute__ __getattr__定義されていない属性に対して実行する--つまり、属性はインスタンスに格納されていないか、親の1つから を継承していない. __getattribute__各属性については、属性アクセスをスーパークラスに渡すことによって再帰ループ が発生しないように注意する必要がある.
例
注意使用_setattr__および_getattribute__ループを避けるには
__getattr__および_getattribute__比較 __getattr__定義されていない属性をブロックし、定義された属性は をブロックしません. __getattribute__すべての属性取得をブロックし、管理されていない属性アクセスをスーパークラス取得器に指し示す必要があり、ループ を回避する.
プロパティ・プロトコルを使用すると、特定のプロパティのgetおよびset操作を、プロパティ・アクセス時にコードを自動的に実行できるように、提供された関数またはメソッドに指定できます.
*基礎知識
attribute=property(fget,fset,fdel,doc)の4つのパラメータは、属性attributeのget,set,delメソッド、ドキュメント情報をそれぞれ表します.
#-*-coding:UTF-8-*-
class Person:
def __init__(self,name):
self._name = name
def getName(self):
print('fetch...')
return self._name
def setName(self,value):
self._name = value
print('change...')
def delName(self):
print('remove...')
del self._name
name = property(getName,setName,delName,'name property docs') # name property name
if __name__ == '__main__':
bob = Person('Bob Smith')
print(bob.name) # getName name
bob.name = 'Robert Smth' # setName
print(bob.name)
del bob.name
print(Person.name.__doc__)
####
fetch...
Bob Smith
change...
fetch...
Robert Smth
remove...
name property docs
[Finished in 0.3s]
すべてのクラスプロパティと同様に、インスタンスと下位のサブクラスはプロパティを継承します.
class Coder(Person):
pass
if __name__ == '__main__':
bob = Coder('Bob Smith')
print(bob.name)
###
fetch...
Bob Smith
Coder Person name
計算プロパティ
class PropSquare:
def __init__(self, start):
self.value = start
def getX(self):
return self.value**2
def setX(self,value):
self.value = value
X = property(getX,setX)
if __name__ == '__main__':
P = PropSquare(3)
Q = PropSquare(32)
print(P.X)
P.X = 4
print(P.X)
print(Q.X)
###
9
16
1024
装飾を使用してプロパティを記述する
#-*-coding:UTF-8-*-
"""
@decorator
def func(args):...
def func(args):...
func = decorator(func)
"""
class Person:
def __init__(self, name):
self._name = name
@property
def name(self):
"""name property docs"""
print('fetch.....')
return self._name
@name.setter
def name(self,value):
print('change')
self._name = value
@name.deleter
def name(self):
print('remove...')
del self._name
if __name__ == '__main__':
rose = Person('Rose Jhon')
print(rose.name)
rose.name = 'Roose Jhon'
print(rose.name)
del rose.name
###
fetch.....
Rose Jhon
change
fetch.....
Roose Jhon
remove...
。 set del
ディスクリプタ
記述子は、属性アクセスをブロックする代替方法を提供します.プロパティは記述子の一種であり、property内蔵関数は特定のタイプの記述子を作成する簡略化された方法である.ディスクリプタプロトコルを使用すると、プロパティに特定のプロパティのgetおよびset操作を、プロパティにアクセスするときに自動的に実行されるコードを挿入する方法を提供し、プロパティの削除をブロックし、プロパティにドキュメントを提供することができます.記述子は独立したクラスとして作成され、メソッド関数のようにクラス属性に割り当てられます.また、サブクラスとインスタンスで*の基礎知識を継承することもできます.
class Descriptor:
def __get__(self,instance,owner):...
def __set__(self,instance,value):...
def __delete__(self,instance):.....
これらのメソッドを持つクラスは記述子と見なすことができ、あるインスタンスが別のクラスのプロパティに割り当てられた場合、これらのメソッドは特殊です.プロパティにアクセスすると自動的に呼び出されます.記述子パラメータ:記述子クラスインスタンス(self)と記述子インスタンスに追加されたクライアントクラスのインスタンス(instance)が渡されます.get__アクセスメソッドはまた、記述子インスタンスが追加するクラスを指定するownerパラメータを追加的に受信します.
#-*-coding:UTF-8-*-
"""
"""
class Name:
def __get__(self,instance,owner):
print(self,instance,owner)
return instance._name
def __set__(self,instance,value):
print('change')
instance._name = value
def __delete__(self,instance):
print('remove')
del instance._name
"""
"""
class Person:
def __init__(self,name):
self._name = name
name = Name()
"""
self Name
instance Person
owner Person
"""
if __name__ == '__main__':
bob = Person('Jim Green')
print(bob.name)
bob.name = 'Jam Green'
del bob.name
###
<__main__.name object="" at=""> <__main__.person object="" at="">
Jim Green
change
remove
記述子の計算プロパティ
class DescSquare:
def __init__(self,start):
self.value = start
def __get__(self,instance,owner):
return self.value**2
def __set__(self,instance,value):
self.value = value
class Client1:
X = DescSquare(3) #
if __name__ == '__main__':
c1 = Client1()
print(c1.X)
print(Client1.X)
ディスクリプタでのステータス情報の使用
"""
"""
class DescState:
def __init__(self,value):
self.value = value
def __get__(self,instance,owner):
print('DescState get')
return self.value*10
def __set__(self,instance,value):
print('DescState set')
self.value = value
class CalcAttrs:
X = DescState(2)
Y = 3
def __init__(self):
self.Z = 4
if __name__ == '__main__':
obj = CalcAttrs()
print(obj.X,obj.Y,obj.Z)
####
value , CalcAttrs value
記述子クラスの属性ではなく、顧客クラスに添付されたインスタンスを格納または使用する属性です.
class InsState:
def __get__(self,instance,owner):
print('InsState get')
return instance._Y*100
def __set__(self,instance,value):
print('InsState set')
instance._Y = value
class CalcAttrs1:
X = DescState(2)
Y = InsState()
def __init__(self):
self._Y = 3
self.Z = 4
if __name__ == '__main__':
obj = CalcAttrs1()
print(obj.X,obj.Y,obj.Z)
###
DescState get
InsState get
20 300 4
CalcAttrs1 (instance)
instance._Y obj 。 obj.Y InsState Y __get__
__getattr__および_getattribute__
def __getattr__(self,name): #On undefined attribute fetch [obj.name]
def __getattribute__(self,name):#on all attribute fetch [obj.name]
def __setattr__(self,name,value):#on all attribute assignment [obj.name=value]
def __delattr__(self,name): #on all attribute deletion [del obj.name]
self ,name ,value
例
#-*-coding:UTF-8-*-
class Catcher:
def __getattr__(self,name):
print('Get:',name)
def __setattr__(self,name,value):
print('Set:',name,value)
def test(slef):
print('test')
class Wrapper:
def __init__(self,obj):
self.wrapper = obj
def __getattr__(self,attrname):
print('Trace:',attrname)
return getattr(self.wrapper,attrname)
if __name__ == '__main__':
X = Catcher()
X.job
X.pay = 99
Y = Wrapper(X)
Y.test()
###
Get: job
Set: pay 99
Trace: test
test
####
Catcher X X.job , getattr ( )
注意使用_setattr__および_getattribute__ループを避けるには
#-*-coding:UTF-8-*-
class Person:
def __init__(self,name):
self._name = name
# def __getattr__(self,attr):
# if attr == 'name':
# print('fetch....')
# return self._name
# else:
# raise AttributeError(attr)
def __getattribute__(self,attr):
if attr == 'name':
print('fetch')
attr = '_name'
return object.__getattribute__(self,attr)
def __setattr__(self,attr,value):
if attr=='name':
print('change...')
attr = '_name'
print(attr)
self.__dict__[attr] = value # self._name = value
def __delattr__(self,attr):
if attr == 'name':
print('remove...')
attr = '_name'
del self.__dict__[attr]
if __name__ == '__main__':
bob = Person('Bob Smith')
print(bob.name)
bob.name = 'Robert Smith'
print(bob.name)
del bob.name
print('-'*20)
sue = Person('Sue Jones')
print(sue.name)
- self._name = name __setattr__
__getattr__および_getattribute__比較