Frage

Wie kann ich Methoden und Datenelemente in Python privat? Oder ist Python nicht Unterstützung private Mitglieder?

War es hilfreich?

Lösung

  

9.6. Private Variablen

     

„Private“ Instanz-Variablen, die   kann nur von innen zugänglich   ein Objekt, existiert nicht in Python.   Allerdings gibt es eine Konvention, die ist   gefolgt von den meisten Python-Code: ein Name   vorangestellt mit einem Unterstrich (z.B.   _spam) sollte als ein nicht-öffentlichen Teil der API behandelt werden (ob es   ist eine Funktion, ein Verfahren oder eine Daten   Mitglied). Es sollte in Betracht gezogen einem   Implementierungsdetail und unterliegen   Änderungen vorbehalten.

     

Da es ein gültiger Anwendungsfall für   Klasse-private Mitglieder (nämlich zu vermeiden   Namenskonflikte von Namen mit Namen   definiert durch Subklassen), besteht   begrenzte Unterstützung für einen solchen Mechanismus,   Namen Mangeln genannt. Jeder Bezeichner   von der Form __spam (mindestens zwei   führenden Unterstrichen, höchstens ein   nacheilenden Unterstrich) ist textlich   mit _classname__spam ersetzt, wobei   classname ist der aktuelle Klassenname   mit Unterstrich (en) gestrippt.   Diese Mangeln wird ohne Rücksicht getan   auf die syntaktische Position der   Identifikator, solange sie auftritt   innerhalb der Definition einer Klasse.

Also, zum Beispiel ,

class Test:
    def __private_symbol(self):
        pass
    def normal_symbol(self):
        pass

print dir(Test)

AUSGABE:

['_Test__private_symbol', 
'__doc__', 
'__module__', 
'normal_symbol']

__private_symbol sollte eine private Methode in Betracht gezogen werden, aber es wäre noch zugänglich durch _Test__private_symbol sein.

Andere Tipps

Die anderen Antworten geben die technischen Details. Ich möchte den Unterschied in der Philosophie zwischen Python auf der einen Seite und Sprachen wie C ++ / Java betonen (was ich Sie kennen nehme an mit auf der Grundlage Ihrer Frage).

Die allgemeine Haltung in Python (und Perl für diese Angelegenheit) ist, dass die ‚Privatsphäre‘ ein Attributs ist eine Anforderung an den Programmierer anstatt einem Stacheldrahtzaun vom Compiler / Interpreter. Die Idee ist gut zusammengefasst in dieser Mail und wird oft bezeichnet wie da es ‚geht davon aus‘, dass der Programmierer ist verantwortlich genug, um nicht einmischen mit der Innen „Wir sind alle Erwachsene zustimmende“. Die führenden Unterstrichen dienen als höfliche Meldung, dass das Attribut intern ist.

Auf der anderen Seite, wenn Sie Sie die Interna für einige Anwendungen zugreifen möchten (ein bemerkenswertes Beispiel Dokumentation Generatoren wie pydoc ist), du bist frei, dies zu tun. Onus auf Sie ist wie ein Programmierer zu wissen, was Sie tun und tun es richtig und nicht auf der Sprache, die Sie Dinge zu erzwingen tun es Art und Weise.

Es gibt keine private von anderen Zugriffsschutzmechanismen in Python. Es ist eine Konvention, dokumentiert in der Python Style Guide zur Anzeige für die Nutzer Ihre Klasse, dass sie nicht bestimmtes Attribut zugreifen.

  • _single_leading_underscore: schwach "internen Gebrauch" -Anzeige. Z.B. from M import * nicht importieren Objekte, deren Name beginnt mit einem Unterstrich.

  • single_trailing_underscore_: vereinbarungsgemäß zu vermeiden Konflikte mit Python-Schlüsselwort verwendet, z.B. Tkinter.Toplevel(master, class_='ClassName')

  • __ double_leading_underscore:., Wenn ein Klassenattribut Benennung ruft Namen Mangeln (innen Klasse FooBar, __boo wird _FooBar__boo, siehe unten)

  

Wenn der Name einer Python-Funktion,   Klassenmethode oder Attribut beginnt mit   (Aber nicht am Ende mit) zwei   Unterstrichen, es ist privat; alles   sonst ist öffentlich. Python hat kein Konzept   geschützter Klassenmethoden (zugänglich   nur in ihrer eigenen Klasse und Nachkommen   Klassen). Klassenmethoden sind entweder   privat (zugänglich nur in ihrem eigenen   Klasse) oder öffentlich (erreichbar von   überall).

Dive Into Python

Python unterstützt keine Privatsphäre direkt. Programmierer müssen wissen, wann es sicher ist Attribut von außen zu ändern, aber trotzdem mit Python können Sie so etwas wie privat mit kleinen Tricks erreichen. Nun lasst uns sehen, eine Person etwas privat setzen kann oder nicht.

class Person(object):

    def __priva(self):
        print "I am Private"

    def publ(self):
        print " I am public"

    def callpriva(self):
        self.__priva()

Nun, wenn wir ausführen:

>>> p = Person()
>>> p.publ()
 I am public
>>> p.__priva()
Traceback (most recent call last):
  File "", line 1, in 
    p.__priva()
AttributeError: 'Person' object has no attribute '__priva'
​#Explanation   : You can see  here we are not able to fetch that private method directly.
>>> p.callpriva()
I am Private
#​Explanation  : Here we can access private method inside class​

Dann, wie jemand kann diese Variable zugreifen ???
Sie können wie tun:

>>>p._Person__priva
I am Private

wow, eigentlich, wenn Python ist immer eine Variable mit doppeltem Unterstrich beginnt, wird „übersetzt“ durch einen einzigen Unterstrich des Hinzufügen und die Klassennamen zum Anfang:

Hinweis: Wenn Sie diesen Namen nicht zu ändern wollen, aber Sie wollen immer noch ein Signal senden für andere Objekte zu bleiben, können Sie einen einzelnen Strich am Anfang Namen mit einem Unterstrich am Anfang verwenden, ist nicht mit Sterne-Importen importiert (aus dem Modul Import *)
Beispiel:

#test.py
def hello():
    print "hello"
def _hello():
    print "Hello private"

#----------------------
#test2.py
from test import *
print hello()
print _hello()

Ausgabe ->

hello
Traceback (most recent call last):
  File "", line 1, in 
NameError: name '_hello' is not defined

Wenn wir nun manuell aufrufen _hello wird.

#test2.py
from test import _hello , hello
print hello()
print _hello()

Ausgabe ->

hello
hello private

Endlich: Python ist nicht wirklich eine Equivalent Privacy Unterstützung hat, obwohl einzelne und Doppelanfangs Unterstrichen zu einem gewissen Grad geben Sie zwei Ebenen der Privatsphäre

Dies könnte funktionieren:

import sys, functools

def private(member):
    @functools.wraps(member)
    def wrapper(*function_args):
      myself = member.__name__
      caller = sys._getframe(1).f_code.co_name
      if (not caller in dir(function_args[0]) and not caller is myself):
         raise Exception("%s called by %s is private"%(myself,caller))
      return member(*function_args)
    return wrapper

class test:
   def public_method(self):
      print('public method called')

   @private
   def private_method(self):
      print('private method called')

t = test()
t.public_method()
t.private_method()

Das ist irgendwie ein l-o-n-g Antwort, aber ich denke, es ist an der Wurzel des echten Problem wird hier - Umfang der Sichtbarkeit. Hängen Sie einfach dort, während ich durch diese Schinderei!

Sie einfach ein Modul importieren muss nicht unbedingt die Anwendungsentwickler Zugriff auf alle seine Klassen oder Methoden geben; wenn ich das Modul Quellcode nicht wirklich sehen kann, wie ich will wissen, was verfügbar ist? Irgend jemand (oder etwas) hat mir zu sagen, was ich tun kann, und erklären, wie die Verwendung diejenigen Funktionen, die ich für einen Benutzer bin, sonst ist das Ganze nutzlos für mich.

Diese Entwicklung höherer Ebene Abstraktionen basiert auf grundlegenden Klassen und Methoden über importierte Module sind mit einem Spezifikationsdokument präsentiert - nicht die eigentlichen Quellcode.

Die Modul Spezifikation beschreibt alle Funktionen sichtbar an den Client-Entwickler sein sollten. Bei großen Projekten und Software-Projektteams zu tun, sollte die tatsächliche Implementierung eines Moduls bleibt immer von denen, versteckt es mit - es ist eine Blackbox mit einer Schnittstelle zur Außenwelt. Für OOD Puristen, glaube ich, die techie Begriffe „Entkopplung“ und „Kohärenz“ sind. Der Modul Benutzer muss weiß nur die Interface-Methoden, ohne mit den Details der Umsetzung zur Last fallen.

Ein Modul sollte nie ohne erste Änderung sein zugrunde liegendes spec Dokuments geändert werden, die Prüfung / Genehmigung in einigen früheren Organisationen erfordern, den Code zu ändern.

Als Hobby-Programmierer (jetzt im Ruhestand), hat ich ein neues Modul mit dem spec doc tatsächlich beginnt als riesigen Kommentarblock an der Spitze des Moduls geschrieben, wird dies der Teil sein, der Benutzer tatsächlich in der Spec-Bibliothek sieht. Da es nur ich bin, habe ich noch eine Bibliothek einzurichten, aber es wäre einfach genug zu tun.

Dann beginnen Codierung ich durch die verschiedenen Klassen schreiben und Methoden, aber ohne Funktionskörper - nur null print-Anweisungen wie „print ()“ - gerade genug, um das Modul zu ermöglichen, ohne Syntaxfehler zu kompilieren. Wenn dieser Schritt abgeschlossen ist, ich das fertige Null-Modul kompilieren - das ist mein spec. Wenn ich an einem Projekt-Team arbeite, würde ich dieses spec / Schnittstelle zur Überprüfung präsentiert und Kommentar, bevor Sie fortfahren mit dem Körper konkretisiert.

ich zu einer Zeit, die Körper jedes Verfahren ein Fleisch und entsprechend zusammenstellen, Syntax sicherzustellen Fehler sofort on-the-fly fixiert sind. Dies ist auch eine gute Zeit, um einen temporären „main“ Ausführungsabschnittes am unteren Schreiben zu beginnen jede Methode zu testen, wie Sie sie codieren. Wenn die Codierung / Tests abgeschlossen sind, alle Testcode wird kommentiert, bis Sie es wieder benötigen, sollten notwendigen Updates werden.

In einem realen Entwicklungsteam, das spec Kommentarblock würde auch in einem Dokument-Control-Bibliothek erscheinen, aber das ist eine andere Geschichte. Der Punkt ist:. Sie als Modul-Client finden Sie nur diese Spezifikation und den Quellcode

PS: lange vor dem Beginn der Zeit arbeitete ich in der Verteidigung Luft-und Raumfahrt-Community und wir haben ein paar ziemlich coole Sachen, aber Dinge wie proprietäre Algorithmen und sensible Systeme Steuerungslogik wurden fest gewölbt und verschlüsselt in Super-Duper sichere Software-Bibliotheken. Wir hatten Zugriff auf Modul / Paket-Schnittstellen, nicht aber die Blackbox Führungsstellen. Es war ein Dokumenten-Management-Tool, das all System-Level-Design behandelt, Software-Spezifikationen, Quellcode und Prüfprotokolle - alles zusammen synchronisiert wurde. Die Regierung hatte strenge Anforderungen Software-Qualitätssicherungsstandards. Erinnert sich noch jemand eine Sprache namens „Ada“? Das ist, wie alt ich bin!

verwende ich Python 2.7 und 3.5. Ich schrieb diesen Code:

class MyOBject(object):
    def __init__(self):
        self.__private_field = 10


my_object = MyOBject()
print(my_object.__private_field)

lief es und bekam:

  

Attribute: 'myObject' Objekt hat kein Attribut '__private_field'

Bitte beachten Sie: https://www.tutorialsteacher.com/python/ privater-und-geschützter Zugang-Modifikatoren-in-python

Wenn Sie eine Methode oder Datenelemente in Python privat machen, verwenden __setattr __

class Number:
    def __init__(self,value):
        self.my_private = value

    def __setattr__(self, my_private, value):
        # the default behavior
        # self.__dict__[my_private] = value
        raise Exception("can't access private member-my_private")


def main():
    n = Number(2)
    print(n.my_private)

if __name__ == '__main__': 
    main()
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top