Seite 1 von 1

public,private in Klassen

Verfasst: Montag 29. August 2005, 17:27
von abc
Gibt es eigentlich eine Methode, in Python-Klassen Properties oder Methoden
im Zugriff zu beschränken, sodaß nur innerhalb dieser Klasse darauf
zugegriffen werden kann, ähnlich wie mit "private" in Ruby oder C++ ?

Wenn nicht: Gibt es eine gute Begründung, wieso das nicht notwendig ist oder
wie man das mit den vorhandenen Python-Elementen nachbilden kann ?

Verfasst: Montag 29. August 2005, 19:07
von ProgChild
Es gibt in Python kein Privat. Wenn du eine Funktion oder eine Variable als Privat deklarieren möchtest, dann stell dem Funktionsnamen einfach einen Unterstrich vorran. Dann weiß Jeder: "Finger weg!" Dass ist eine allgemeine Absprache.

Die Privat Deklaration in C++ lässt sich leicht umgehen. Warum soll man sich so ein System zusammen basteln? Außerdem hat Python ne schöne Art Eingenschaften zu Kapseln, so dass das eigentliche Argument für Private Variablen wegfällt. Falls man es doch braucht; Es gibt noch den Unterstrich.

re

Verfasst: Montag 29. August 2005, 19:24
von abc
Danke.

private in C++ läßt sich sicherlich vielfach umgehen, aber dieses Sprachelement ist ja in erster Linie dazu gedacht, um den
Programmierer zur Selbstdisziplin zu erziehen und nicht, um ihn zum "Attackieren" des private-Mechanismus in seinen eigenen Klassen zu
animieren :)

Ich stimme dennoch zu, daß der public/private-Mechanismus im
Objekt-Modell von C++ sicherer sein könnte als er ist - z.B. sollte es nicht
möglich (oder nur unter Warnungen möglich) sein, non-const Zeiger auf
private-Daten eines Objekts zurückzugeben, denn mithilfe des zurückgegebenen Zeigers kann der Anwender einer Klasse munter "private"-Properties der Klasse ändern.

Verfasst: Montag 29. August 2005, 19:36
von jens
Ich hab's mal in die FAQ aufgenommen: http://www.pythonwiki.de/PythonDeForum/ ... 662eefcc64

@ProgChild: Hab deine Erklärung 1-zu-1 übernommen, ich hoffe du hast nicht's dagegen 8)

Re: re

Verfasst: Dienstag 30. August 2005, 00:58
von BlackJack
abc hat geschrieben:Ich stimme dennoch zu, daß der public/private-Mechanismus im
Objekt-Modell von C++ sicherer sein könnte als er ist - z.B. sollte es nicht
möglich (oder nur unter Warnungen möglich) sein, non-const Zeiger auf
private-Daten eines Objekts zurückzugeben, denn mithilfe des zurückgegebenen Zeigers kann der Anwender einer Klasse munter "private"-Properties der Klasse ändern.
Und man sollte dem Präprozessor folgendes verbieten:

Code: Alles auswählen

#define private public
Das ist eine ziemliche "Sicherheitslücke". :wink:

Verfasst: Samstag 3. September 2005, 15:50
von Masaru
Hm .. also regulär kann man nicht nur einfach mit einem Unterstrich vorweg _ Klassenmethoden/Variabel auf "private" stellen dachte ich, sondern für direkten Zugriff von aussen (als Attribut) via 2 Unterstriche sperren.

Bsp.:

Code: Alles auswählen

>>> class test:
... 	def __init__(self):
... 		self.lang = 'Python'
... 		self.__name = 'test'
... 	def get_lang(self):
... 		return self.lang
... 	def __get_name(self):
... 		return self.__name
... 	def get_name_pls(self):
... 		return self.__name
... 	
>>> t = test()
>>> 
>>> t.lang
'Python'
>>> t.__name
Traceback (most recent call last):
  File "<interactive input>", line 1, in ?

AttributeError: test instance has no attribute '__name'
>>> 
>>> t.get_lang()
'Python'
>>> t.__get_name()
Traceback (most recent call last):
  File "<interactive input>", line 1, in ?
AttributeError: test instance has no attribute '__get_name'
>>> 
>>> t.get_name_pls()
'test'
>>> 
Zwei Unterstriche sind meines Wissens nach eine Art hidden (es gibt noch tricks, sie von aussen aufzurufen, aber nicht eben als einfaches Objektattribut).

Ein Unterstrich bedeutet ebenfalls Hidden, aber von Erbenden Unterklassen dennoch weiterhin aufrufbar.

Hat wer andere Infos sonst?

>>Masaru<<

Verfasst: Samstag 3. September 2005, 23:24
von BlackJack
Masaru hat geschrieben:Hm .. also regulär kann man nicht nur einfach mit einem Unterstrich vorweg _ Klassenmethoden/Variabel auf "private" stellen dachte ich, sondern für direkten Zugriff von aussen (als Attribut) via 2 Unterstriche sperren.
Nicht wirklich sperren. Da wird einfach nur ein bischen "name mangling" betrieben. Das Attribut ist da, aber mit einem anderen Namen von aussen gesehen. Es wird einfach nur der Klassenname mit einem führenden Unterstrich noch vor den Attributnamen gehängt. Und so kann man das auch Aufrufen:

Code: Alles auswählen

n [55]: class A:
   .55.:   def __test(self):
   .55.:     print 'called "hidden" method'
   .55.:

In [56]: a = A()

In [57]: a._A__test()
called "hidden" method
Zwei Unterstriche sind meines Wissens nach eine Art hidden (es gibt noch tricks, sie von aussen aufzurufen, aber nicht eben als einfaches Objektattribut).
Doch, man muss nur wissen wie die Klasse heisst. Bei ``dir(a)`` wird die Methode auch brav mit aufgelistet. Ist also wirklich nicht versteckt.

Grundsätzlich sollte man sich gut überlegen ob man das braucht. Es geht nämlich nicht darum den Zugriff von aussen zu verhindern, sondern Namenskollisionen bei erbenden Klassen zu vermeiden. Wenn man damit Probleme bekommt, dann hat man die Klassen(hierarchie) wahrscheinlich sowieso völlig übertrieben. Ist ja schliesslich kein Java. :wink:

Verfasst: Samstag 3. September 2005, 23:39
von Masaru
Genau diese Möglichkeit meine ich.