Frage

Python gibt uns die Möglichkeit, durch das Voranstellen doppelte Unterstrichen auf den Namen, wie diese ‚private‘ Methoden und Variablen innerhalb einer Klasse zu erstellen: __myPrivateMethod(). Wie also kann man das erklären

>>> class MyClass:
...     def myPublicMethod(self):
...             print 'public method'
...     def __myPrivateMethod(self):
...             print 'this is private!!'
... 
>>> obj = MyClass()
>>> obj.myPublicMethod()
public method
>>> obj.__myPrivateMethod()
Traceback (most recent call last):
  File "", line 1, in 
AttributeError: MyClass instance has no attribute '__myPrivateMethod'
>>> dir(obj)
['_MyClass__myPrivateMethod', '__doc__', '__module__', 'myPublicMethod']
>>> obj._MyClass__myPrivateMethod()
this is private!!

Was ist das Problem?!

Ich werde diese ein wenig für diejenigen erklären, die nicht ganz so bekommen haben.

>>> class MyClass:
...     def myPublicMethod(self):
...             print 'public method'
...     def __myPrivateMethod(self):
...             print 'this is private!!'
... 
>>> obj = MyClass()

Was ich tat, es gibt eine Klasse mit einer öffentlichen Methode erstellen und ein eigenes Verfahren und instanziiert es.

Als nächstes rufe ich seine öffentliche Methode.

>>> obj.myPublicMethod()
public method

Als nächstes versuche ich, und seine private Methode nennen.

>>> obj.__myPrivateMethod()
Traceback (most recent call last):
  File "", line 1, in 
AttributeError: MyClass instance has no attribute '__myPrivateMethod'

Alles sieht hier gut; wir sind nicht in der Lage, es zu nennen. Es ist in der Tat, ‚privat‘. Na ja, eigentlich ist es nicht. Ausführen von dir () auf dem Objekt eine neue magische Methode zeigt, dass Python auf magische Weise für alle Ihre ‚privaten‘ Methoden erstellt.

>>> dir(obj)
['_MyClass__myPrivateMethod', '__doc__', '__module__', 'myPublicMethod']

Der Name dieser neuen Methode ist immer ein Unterstrich, durch den Klassennamen, gefolgt von dem Methodennamen gefolgt.

>>> obj._MyClass__myPrivateMethod()
this is private!!

So viel zur Verkapselung, wie?

Auf jeden Fall würde ich immer gehört, Python nicht Verkapselung nicht unterstützt, also warum auch versuchen? Was soll das?

War es hilfreich?

Lösung

Der Name wird Scrambling verwendet, um sicherzustellen, dass Unterklassen die privaten Methoden und Attribute ihrer Oberklassen nicht versehentlich überschrieben werden. Es ist nicht zu verhindern, dass bewusster Zugang von außen ausgelegt.

Zum Beispiel:

>>> class Foo(object):
...     def __init__(self):
...         self.__baz = 42
...     def foo(self):
...         print self.__baz
...     
>>> class Bar(Foo):
...     def __init__(self):
...         super(Bar, self).__init__()
...         self.__baz = 21
...     def bar(self):
...         print self.__baz
...
>>> x = Bar()
>>> x.foo()
42
>>> x.bar()
21
>>> print x.__dict__
{'_Bar__baz': 21, '_Foo__baz': 42}

Natürlich ist es bricht, wenn zwei verschiedene Klassen den gleichen Namen haben.

Andere Tipps

Beispiel für private Funktion

import re
import inspect

class MyClass :

    def __init__(self) :
        pass

    def private_function ( self ) :
        try :
            function_call = inspect.stack()[1][4][0].strip()

            # See if the function_call has "self." in the begining
            matched = re.match( '^self\.', function_call )
            if not matched :
                print 'This is Private Function, Go Away'
                return
        except :
            print 'This is Private Function, Go Away'
            return

        # This is the real Function, only accessible inside class #
        print 'Hey, Welcome in to function'

    def public_function ( self ) :
        # i can call private function from inside the class
        self.private_function()

### End ###

Als ich zuerst von Java nach Python kam I gehasst diese. Es erschreckt mich zu Tode.

Heute könnte es nur sein, die eine Sache, Ich liebe die meisten über Python.

Ich liebe auf einer Plattform zu sein, wo die Menschen einander vertrauen und nicht das Gefühl, wie sie sich um ihren Code undurchdringlichen Mauern bauen müssen. In stark gekapselt Sprachen, wenn eine API einen Fehler hat, und Sie haben herausgefunden, was schief geht, können Sie immer noch nicht in der Lage sein, um es zu arbeiten, weil die benötigte Methode privat ist. In Python ist die Haltung: „sicher“. Wenn Sie glauben, die Situation zu verstehen, vielleicht haben Sie es sogar lesen, dann alles, was wir sagen können, ist „viel Glück!“.

Denken Sie daran, Verkapselung nicht einmal schwach zu „Sicherheit“ im Zusammenhang, oder die Kinder aus dem Rasen zu halten. Es ist nur ein weiteres Muster, das verwendet werden soll, eine Code-Basis leichter verständlich zu machen.

http://www.faqs.org/docs/diveintopython/fileinfo_private.html

  

Genau genommen private Methoden sind   außerhalb ihrer Klasse zugänglich, nur   nicht leicht zugänglich. Nichts in   Python ist wirklich privat; im Inneren,   die Namen von privaten Methoden und   Attribute sind verstümmelten und unmangled   on the fly, um sie scheinen   unzugänglich durch ihre Vornamen. Sie   Zugriff auf die __parse Verfahren des Dosen   MP3FileInfo Klasse mit dem Namen   _MP3FileInfo__parse. Bestätigen Sie, dass dies interessant, dann versprechen,   nie, tun Sie es jemals in echten Code.   Private Methoden sind privat für ein   Grund, aber wie viele andere Dinge in   Python, ihre Privatheit ist   letztlich eine Frage der Konvention, nicht   Kraft.

Der Begriff häufig verwendet, ist „wir sind alle Erwachsene zustimmenden hier“. Durch das Voranstellen eines einzelnen Strich (nicht aussetzen) oder Doppelstrich (ausblenden), doch sagen Sie den Benutzer Ihrer Klasse, die Sie das Mitglied beabsichtigen, in irgendeiner Weise ‚privat‘ zu sein. Aber Sie vertrauen, alle anderen verhalten verantwortungsvoll und respektieren, dass, es sei denn, sie haben einen zwingenden Grund, nicht zu (zum Beispiel Debugger, Code-Vervollständigung).

Wenn Sie wirklich etwas haben muss, was privat ist, dann können Sie es in einer Erweiterung implementieren (beispielsweise in C für CPython). In den meisten Fällen jedoch lernen Sie einfach die Pythonic Art und Weise, Dinge zu tun.

Es ist nicht absolut nicht wie um Privatheit der Mitglieder in jeder Sprache (Zeiger arithmetics in C ++, Reflections in .NET / Java) erhalten kann.

Der Punkt ist, dass Sie eine Fehlermeldung erhalten, wenn Sie versuchen, die private Methode durch Zufall zu nennen. Aber wenn man sich in den Fuß schießen wollen, gehen Sie voran und es tun.

Edit:? Sie versuchen Sie nicht, Ihre Sachen durch OO-Verkapselung zu sichern, haben Sie

Die class.__stuff Namenskonvention ermöglicht der Programmierer weiß, dass er nicht __stuff von außen zugreifen soll. Der Name Mangeln macht es unwahrscheinlich, jemand es durch Zufall tun.

Es stimmt, können Sie immer noch dieses Problem umgehen, ist es noch einfacher als in anderen Sprachen (die übrigens auch lassen Sie dies tun), aber kein Python-Programmierer würde dies tun, wenn er über Verkapselung sorgt.

Ein ähnliches Verhalten liegt vor, wenn Modul Attributnamen mit einem einzigen Unterstrich beginnen (zum Beispiel _foo).

Modul Attribute als solche benannt werden nicht in ein Importmodul kopiert werden, wenn die from* Methode verwendet, z.

from bar import *

Dies ist jedoch eine Konvention und keine Sprache Einschränkung. Diese sind nicht private Attribute; sie können von jedem Importeur referenziert und manipuliert werden. Einige argumentieren, dass aus diesem Grunde, Python nicht wahr Verkapselung implementieren kann.

Es ist nur eine dieser Sprache Design-Entscheidungen. Auf einer bestimmten Ebene sind sie gerechtfertigt. Sie machen es, so dass Sie ziemlich weit aus dem Weg gehen müssen, um die Methode zu versuchen, und zu rufen, und wenn Sie es wirklich brauchen, die schlecht, müssen Sie einen ziemlich guten Grund haben!

Debuggen Haken und kamen Tests als mögliche Anwendungen in dem Sinne, verantwortungs natürlich verwendet werden.

Mit Python 3.4 ist dies das Verhalten:

>>> class Foo:
        def __init__(self):
                pass
        def __privateMethod(self):
                return 3
        def invoke(self):
                return self.__privateMethod()


>>> help(Foo)
Help on class Foo in module __main__:

class Foo(builtins.object)
 |  Methods defined here:
 |
 |  __init__(self)
 |
 |  invoke(self)
 |
 |  ----------------------------------------------------------------------
 |  Data descriptors defined here:
 |
 |  __dict__
 |      dictionary for instance variables (if defined)
 |
 |  __weakref__
 |      list of weak references to the object (if defined)

 >>> f = Foo()
 >>> f.invoke()
 3
 >>> f.__privateMethod()
 Traceback (most recent call last):
   File "<pyshell#47>", line 1, in <module>
     f.__privateMethod()
 AttributeError: 'Foo' object has no attribute '__privateMethod'

https://docs.python.org/3/tutorial /classes.html#tut-private

  

Beachten Sie, dass die Mangeln Regeln ausgelegt sind meist um Unfälle zu vermeiden; es noch möglich ist, zuzugreifen oder eine Variable zu ändern, die privat angesehen wird. Dies auch nützlich in besonderen Umständen sein kann, wie in dem Debugger.

Auch wenn die Frage alt ist, ich hoffe, dass mein Snippet hilfreich sein könnte.

Die wichtigste Sorge über private Methoden und Attribute ist es, Entwickler zu sagen nicht, dass es außerhalb der Klasse zu nennen und dies ist Kapselung. kann man die Sicherheit von Verkapselung falsch verstehen. wenn man bewusst Syntax wie die verwendet (unten) Sie erwähnt haben, wollen Sie nicht Kapselung.

obj._MyClass__myPrivateMethod()

Ich habe von C # migriert und anfangs war es auch für mich komisch, aber nach einer Weile kam ich auf die Idee, dass nur die Art und Weise, dass Python-Code Designer denken über OOP unterscheidet.

  

Warum sind Pythons 'private' Methoden nicht wirklich privat?

Wie ich es verstehe, sie nicht privat sein. Wie könnte die Privatsphäre durchgesetzt werden?

Die offensichtliche Antwort ist „private Mitglieder können nur durch self zugegriffen werden“, aber das würde nicht funktionieren - self in Python nicht speziell ist, ist es nichts anderes als eine häufig verwendete Bezeichnung für den ersten Parameter einer Funktion.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top