Heim > Datenbank > MySQL-Tutorial > Python-Deskriptor(1)

Python-Deskriptor(1)

黄舟
Freigeben: 2016-12-23 17:37:18
Original
1213 Leute haben es durchsucht

Python-Deskriptoren sind eine Möglichkeit, verwaltete Eigenschaften zu erstellen. Immer wenn ein Attribut abgefragt wird, wird eine Aktion ausgeführt. Diese Aktion ist standardmäßig „Abrufen“, „Festlegen“ oder „Löschen“. Manchmal stellt eine Anwendung jedoch

mehr Anforderungen und erfordert, dass Sie einige komplexere Aktionen entwerfen. Die beste Lösung besteht darin, eine Funktion zu schreiben, die die gewünschte Aktion ausführt, und dann anzugeben, dass sie ausgeführt wird, wenn auf die Eigenschaft zugegriffen wird. Ein Objekt

mit dieser Funktionalität wird als Deskriptor bezeichnet. Deskriptoren sind die Grundlage für die Implementierung von Python-Methoden, gebundenen Methoden, Super, PRperty, Staticmethod und Classmethod.

1. Deskriptorprotokoll

Ein Deskriptor ist ein Objekt, das einen Attributwert darstellt. Durch die Implementierung einer oder mehrerer Methoden __get__, __set__, __delete__ kann auf den Deskriptor und die Attribute zugegriffen werden Diese Vorgänge können auch individuell angepasst werden.

__get__(selbst, Instanz, eigener): Wird verwendet, um auf Attribute zuzugreifen und den Wert des Attributs zurückzugeben. „Instance“ ist das Instanzobjekt, das den Deskriptor verwendet, und „own“ ist die Klasse, zu der die Instanz gehört. Beim Zugriff auf eine Eigenschaft über eine Klasse ist die Instanz „None“.

__set__(selbst, Instanz, Wert): Attributwert festlegen.

__delete__(self,instance): Attributwert löschen.

2. So implementieren Sie Deskriptoren

Klassendeskriptor (Objekt):
def __get__(selbst, Instanz, Besitzer):
print 'getting:%s'%self. _Name Return Self._name
DEF __SET __ (Selbst, Instanz, Name):
Print'-Einstellung:%s'%name
Self._name = Name
stance ):

Print 'Deleting:%s'%Self._name
Del Self._name
Class Person (Object):
name = descriptionor ()

Ein sehr einfaches Deskriptorobjekt wird generiert. Jetzt können Sie den Attributnamen eines Personenobjekts lesen, festlegen und löschen:

>>> p=Person()

>> del p.name

deleting:john



Hinweis: Deskriptoren können nur auf Klassenebene instanziiert werden und können nicht für jedes Deskriptorobjekt in __init__() und anderen Methoden zur Instanzerstellung erstellt werden.

Eigenschaftsnamen, die von Klassen mit Deskriptoren verwendet werden, haben eine höhere Priorität als in Instanzen gespeicherte Eigenschaftsnamen. Damit ein Deskriptor einen Wert auf einer Instanz speichern kann, muss der Deskriptor einen Namen auswählen, der sich von dem Namen unterscheidet, den er selbst verwendet.

Wie im obigen Beispiel kann die Person-Klasseninitialisierungsfunktion __init__ den Namen nicht zum Festlegen von Attributen für die Instanz verwenden.

Datendeskriptor und Nicht-Daten-Deskriptor:

Wenn __get__ und __set__ implementiert sind, handelt es sich um einen Datendeskriptor. Wenn nur __get__ implementiert ist, handelt es sich um einen Nicht-Daten-Deskriptor. Der unterschiedliche Effekt besteht darin, dass der Datendeskriptor immer die Attributimplementierung in einer Instanz ersetzt

und der Nicht-Datendeskriptor keinen Satz hat, wenn Attributen über die Instanz Werte zugewiesen werden, wie oben p.name = 'hello', die Methode __set__ wird nicht mehr aufgerufen und das Instanzattribut p.name wird direkt auf 'hello' gesetzt.

Wenn Sie AttributeError nur in __set__ auslösen, erhalten Sie natürlich immer noch einen Nicht-Daten-Deskriptor.

Deskriptor-Aufrufmechanismus:

Wenn Python beim Abfragen des Attributs a.attr eines Objekts feststellt, dass attr ein Deskriptorobjekt ist, hängt das Lesen des Attributs vom Objekt a ab:

Direkter Aufruf: Der einfachste Aufruf besteht darin, den Code direkt zum Aufrufen der Deskriptormethode attr.__get__(a) zu verwenden

Instanzbindung: Wenn a ein Instanzobjekt ist, rufen Sie die Methode auf: type( a).__dict__ ['attr'].__get__(a,type(a))

Klassenbindung: Wenn A ein Klassenobjekt ist, rufen Sie die Methode auf: A.__dict__['attr'].__get__( None,A)

Superbindung: Wenn a eine Superinstanz ist, dann findet super(B,obj).m() die Basisklasse A von B durch Abfrage von obj.__class__.__mro__ und führt dann A.__dict__ aus ['m' ].__get__(obj,obj.__class__)

3. Deskriptor, der die Attributtypprüfung durchführt

class TypedProperty(object):
def __init__(self,name,attr_type,default=None):
self.name='_'+name
self.type=attr_type
self .default=default if default else attr_type()
def __get__(self,instance,own):
return getattr(instance,self.name,self.default)
def __set__(self,instance,value ):
if not isinstance(value,self.type):
raise TypeError,'Must be %s'%self.type
setattr(instance,self.name,value)
def __delete__ (self,instance):
raise AttributeError('Attribut kann nicht gelöscht werden')
class Foo(object):
name=TypedProperty('name',str)
num=TypedProperty('num ',int,37)                                                                                                                & auf den Typ int gesetzt, ein Fehler wird gemeldet:

>>> f.name=21

TypeError: Muss sein;

Und das Löschen von Attributen ist verboten:

>>> del f.name

AttributeError: Attribut kann nicht gelöscht werden

f.name unsichtbarer Aufruftyp(f).__dict__['name ']. __get__(f,Foo), also Foo.name.__get__(f,Foo).

Der obige Deskriptor wird tatsächlich auf f._name über setattr(f,_name,value) gespeichert, und num wird auf f._num gespeichert.

Andernfalls kollidiert der Deskriptorname name mit dem Instanzattributnamen und das Deskriptorattribut f.name überschreibt das Instanzattribut f.name.

Das Obige ist der Inhalt des Python-Deskriptors (1). Weitere verwandte Inhalte finden Sie auf der chinesischen PHP-Website (www.php.cn)!


Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage