2017-04-20 7 views
0

Ich denke, es ist einfacher für mich zu erklären, was ich versuche, mit einem einfachen Beispiel zu erreichen. Betrachten Sie den folgenden Code:Methode verketten und auf Variablen zugreifen

Offensichtlich schlägt die Assertion fehl, da sich die Attribute auf die Methoden und nicht auf die Variablen beziehen. Ich habe versucht, mit der __getattribute__ Methode zu verwirren, so dass es "Alter" zu "_age" löst, aber ich kann anscheinend keinen Weg finden, wo beide Fälle funktionieren, und ich bin nicht ganz sicher, dass es überhaupt möglich ist außer Python hat mich vorher überrascht.

+0

Wenn Sie wirklich Verstecken von Daten verwenden möchten, hier ist ein [Beispiel] (http://stackoverflow.com/questions/6304040/real-world-Beispiel-über-how-to-use-Eigenschaft-Feature-in-Python/42300481 # 42300481) von Eigenschaften, die Ihnen den Anfang machen sollten. – Mike

Antwort

2

Kurze Antwort: Nicht. Sie werden Probleme bekommen, jeder, der Ihren Code benutzt/liest, wird Probleme bekommen, und es ist nicht die Zeit wert, die Sie damit verbringen, ihn zu implementieren.


Lange Antwort: Wenn Sie unbedingt, könnten Sie eine Klasse erstellen, die den Wert des Attribut legt, wenn sie aufgerufen, und sonst imitiert das Verhalten des Wert. Um dies zu tun, müssen Sie alle die magic methods überschreiben und selbst dann Dinge wie print(type(p.age)) wird nicht die erwartete Ausgabe von <class 'int'> produzieren.

Hier ist ein Ausschnitt Sie (nur mit dem __eq__ Methode implementiert), um loszulegen:

class CallableAttribute: 
    def __init__(self, owner, name): 
     self.owner= owner 
     self.name= name 

     setattr(owner, name, self) 
     self(None) 

    def __call__(self, value): 
     setattr(self.owner, '_'+self.name, value) 
     return self.owner 

    @property 
    def _value(self): 
     return getattr(self.owner, '_'+self.name) 

    def __eq__(self, other): 
     return self._value==other 

class Person(object): 
    def __init__(self): 
     CallableAttribute(self, 'age') 
     CallableAttribute(self, 'gender') 
+0

Sie haben wahrscheinlich Recht, und ich sollte wahrscheinlich die Design-Entscheidungen überdenken. Eine kurze Folgefrage: Wenn ich addiere: assert p.age * 2 == 20, bekomme ich TypeError: nicht unterstützte Operandentyp (en) für *: 'instance' und 'int' - Gibt es eine Möglichkeit dies zu umgehen in eine elegante Art und Weise? –

+0

@MattImmer Ja, Sie überschreiben einfach die ['__mul__'] (https://docs.python.org/3/reference/datamodel.html#object.__mul__) Funktion. –

+0

Danke! Ich werde feststellen, dass es möglich ist, aber schlechte Praxis, dies zu tun und könnte ein alternatives Design in Betracht ziehen. –

Verwandte Themen