public,private in Klassen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
abc

public,private in Klassen

Beitragvon abc » Montag 29. August 2005, 17:27

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 ?
ProgChild
User
Beiträge: 210
Registriert: Samstag 9. April 2005, 10:58
Kontaktdaten:

Beitragvon ProgChild » Montag 29. August 2005, 19:07

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.
abc

re

Beitragvon abc » Montag 29. August 2005, 19:24

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.
Benutzeravatar
jens
Moderator
Beiträge: 8458
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Beitragvon jens » Montag 29. August 2005, 19:36

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)

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
BlackJack

Re: re

Beitragvon BlackJack » Dienstag 30. August 2005, 00:58

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:
Benutzeravatar
Masaru
User
Beiträge: 425
Registriert: Mittwoch 4. August 2004, 22:17

Beitragvon Masaru » Samstag 3. September 2005, 15:50

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<<
BlackJack

Beitragvon BlackJack » Samstag 3. September 2005, 23:24

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:
Benutzeravatar
Masaru
User
Beiträge: 425
Registriert: Mittwoch 4. August 2004, 22:17

Beitragvon Masaru » Samstag 3. September 2005, 23:39

Genau diese Möglichkeit meine ich.

Wer ist online?

Mitglieder in diesem Forum: Bing [Bot]