Verhindert den Zugriff auf eine Instanzvariable aus der Unterklasse, ohne die Basisklasse zu beeinflussen

9

Sagen wir, ich habe eine einfache Klasse Foo , die von einer externen Bibliothek kommt, daher kann ich sie nicht direkt ändern:

%Vor%

Ich möchte eine Unterklasse Bar erstellen und verhindern, dass x von einer Instanz von Bar geändert wird, aber weiterhin die Methoden x in Bar verwenden.

Hier ist, was ich versucht habe, und es wird wahrscheinlich die Grundidee aufklären, aber leider funktioniert es nicht:

%Vor%

Im Grunde habe ich einige Wrapper-Funktionen ( do_stuff() ) um ein Attribut herum angelegt, und jetzt möchte ich verhindern, dass das Attribut direkt geändert wird, da es einige Funktionen der Wrapper-Funktionen durcheinander bringen könnte. Ist das möglich?

Bearbeitet mit einem besseren Beispiel was ich will. Ich versuche nicht zu verhindern, dass sie die Variable x sehen, sondern sie von außerhalb von do_stuff()

ändern     
Markus Meskanen 27.10.2015, 12:55
quelle

3 Antworten

1

Dies sollte viel einfacher zu erreichen sein, wenn Sie bereit sind, die Vererbung zu vermeiden:

%Vor%     
Noctis Skytower 27.10.2015, 14:22
quelle
1

Die kurze Antwort lautet: Nein, das ist nicht sinnvoll möglich.

Pythons Leitsatz hier, um die Phrasierung aus dem style guide ist, dass wir alle verantwortungsbewusste Nutzer sind. Das bedeutet, dass Code vertrauenswürdig ist, um keine albernen Dinge zu tun, und Menschen sollten es generell vermeiden, sich ohne guten Grund mit Mitgliedern anderer Klassen zu messen.

Der erste und beste Weg, um Personen daran zu hindern, versehentlich einen Wert zu ändern, besteht darin, sie mit dem einzelnen Unterstrich ( _variable ) zu markieren. Dies bietet Ihnen jedoch möglicherweise nicht den Schutz, den Sie gegen eine versehentliche Änderung Ihrer Variablen haben möchten.

Der nächste Schritt beim Schutz besteht darin, einen doppelten Unterstrich zu verwenden. Zitieren von PEP-8 :

  

Um Namenskonflikte mit Unterklassen zu vermeiden, verwenden Sie zwei führende Unterstriche, um Pythons Namensänderungsregeln aufzurufen.

     

Python manipuliert diese Namen mit dem Klassennamen: Wenn die Klasse Foo ein Attribut namens __a hat, kann sie nicht von Foo .__ a aufgerufen werden. (Ein eindringlicher Benutzer könnte immer noch Zugriff erhalten, wenn er Foo._Foo__a aufruft.) Im Allgemeinen sollten doppelte führende Unterstriche nur verwendet werden, um Namenskonflikte mit Attributen in Klassen zu vermeiden, die als unterklassifiziert sind.

Das Mangeln erschwert das versehentliche Überschreiben eines Wertes.

Ich habe den letzten Satz betont, weil es wichtig ist. Das Verwenden dieses Mechanismus zum Verhindern von versehentlichem Zugriff auf ein Mitglied ist nicht wirklich das, was für viele Mitglieder getan werden sollte.

In Ihrem speziellen Fall wäre die Art, wie ich das Problem lösen würde, überhaupt keine Unterklasse. Überlegen Sie:

%Vor%

Das bedeutet natürlich, dass Bar alle Methoden von Foo umbrechen muss, die Sie umbrechen möchten. Ja könnte jemand noch,

%Vor%

oder

%Vor%

aber es ist schwerer unbeabsichtigt zu tun.

    
theB 27.10.2015 14:30
quelle
0

Sie befinden sich auf der richtigen Spur. Sie möchten x zu einer Eigenschaft machen, anstatt sie als Attribut in der Unterklasse zu verwenden. Wo Sie falsch gelaufen sind, haben Sie versucht, die Rohdaten für x auf super zu speichern. Sie möchten die Tatsache ausnutzen, dass die Elternklasse die neue Eigenschaft der Unterklasse transparent verwenden kann und nicht wissen muss, dass sie jetzt eine Eigenschaft und kein Attribut ist. So etwas sollte für dich funktionieren:

%Vor%     
Bi Rico 29.10.2015 01:53
quelle