2016-05-11 3 views
3

Lassen Sie uns sagen, dass ich die folgende Descriptor haben:Wie kann ich auf Attribute zugreifen, die in Python-Deskriptoren gespeichert sind?

class MyDescriptor(object): 

    def __init__(self, name, type_): 
     self.name = name 
     self.type_ = type_ 

    def __set__(self, obj, value): 
     assert isinstance(value, self.type_) 
     obj.__dict__[self.name] = value 

Gibt es eine Möglichkeit type_ von einem Objekt zuzugreifen MyDescriptor beschäftigt?

heißt

class MyObject(object): 
    x = MyDescriptor('x', int) 

my_object = MyObject() 
my_object.x = 5 
print my_object.x.type_ 

Soweit ich weiß, wird diese erhöhen AttributeError als my_object.x ist ein int. Aber ich frage mich, ob es eine gute Möglichkeit gibt, Metadaten mit Deskriptoren zu verknüpfen.

EDIT: angepasste Formulierung, um anzuzeigen, dass es eine Instanz eines Deskriptors pro Klasse gibt.

+0

Ich glaube nicht, dass es einen Grund gibt, das Feld 'type_' mit dem Unterstrich zu benennen. Für den Parameter macht es Sinn, aber 'self.type' beschattet nichts, also ist es in Ordnung. –

+0

Check out http://StackOverflow.com/Questions/21629397/neat-way-to-get-descriptor-object –

+0

@alex Halle Guter Punkt! Aber obwohl das zutrifft, führt dies in der Praxis zu einem Code wie 'self .__ class __. X.type_' oder' my_object .__ class __. X.type'. Welche, nehme ich an, ist nicht schrecklich. – matthewatabet

Antwort

2

Gibt es eine Möglichkeit type_ von der Objektinstanz zugreifen Wem gehört die MyDescriptor-Instanz?

Es gibt keine Objektinstanz, die die MyDescriptor-Instanz besitzt. Es gibt eine Instanz von MyDescriptor, die auf der Klasse von denen der Deskriptor ein Attribut (MyObject in Ihrem Beispiel) gespeichert ist. So funktionieren Deskriptoren. Sie können auf diese Deskriptorinstanz über die Klasse zugreifen, wie in der Antwort von user2357112 beschrieben. Beachten Sie jedoch, dass Sie auf Daten auf Klassenebene zugreifen. Wenn Sie Daten auf Instanzebene mit dem Deskriptor speichern möchten, müssen Sie sie auf der Instanz selbst (d. H. Auf dem Objekt, das als obj an Ihren __set__/__get__ übergeben wurde) und nicht auf dem Deskriptor speichern.

+0

Dies als die Lösung zu markieren, da es die falsche Annahme in meiner Frage offenbarte und zu einigen hilfreichen Bearbeitungen und einem besseren Vorgehen am Ende führte. Vielen Dank! – matthewatabet

2

Sie müssen auf das eigentliche Deskriptorobjekt zugreifen. Für Ihr Descriptor das kann mit

type(my_object).x.type_ 

oder

MyObject.x.type_ 

für Deskriptoren durchgeführt werden, wo MyObject.x nicht das tatsächliche Descriptor-Objekt ist, wie Funktionen auf Python 2, müssen Sie den Descriptor finden können durch Suchen Sie in der Klasse __dict__, oder schauen Sie sich die Dicts aller Klassen in der MRO an, wenn Sie eine generische Möglichkeit haben wollen, vererbte Deskriptoren zu finden. (Für den speziellen Fall, den ich gerade erwähnt, können Sie auch das __func__ Attribut des ungebundenen Methode Objekts, aber das wird nicht für andere Deskriptoren arbeiten.)

+0

Das stimmt, aber die Frage zeigt an, dass das OP denkt, dass es für jede Instanz von MyObject ein separates Deskriptorobjekt gibt. Da ist nicht. Sie können dies tun, aber wie in meiner Antwort beschrieben, kann es nicht das tun, was das OP hofft. – BrenBarn

Verwandte Themen