Vra

Python gee ons die vermoë om 'private' metodes en veranderlikes binne 'n klas te skep deur dubbele onderstrepings aan die naam voor te sit, soos volg: __myPrivateMethod().Hoe kan mens dit dan verduidelik

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

Wat's die storie?!

Ek sal dit 'n bietjie verduidelik vir diegene wat dit nie heeltemal verstaan ​​het nie.

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

Wat ek daar gedoen het, is om 'n klas met 'n publieke metode en 'n private metode te skep en dit te instansieer.

Vervolgens noem ek sy openbare metode.

>>> obj.myPublicMethod()
public method

Vervolgens probeer ek sy private metode noem.

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

Alles lyk goed hier;ons kan dit nie noem nie.Dit is in werklikheid 'privaat'.Wel, eintlik is dit nie.Hardloop dir() op die voorwerp onthul 'n nuwe magiese metode wat python magies skep vir al jou 'private' metodes.

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

Hierdie nuwe metode se naam is altyd 'n onderstreep, gevolg deur die klasnaam, gevolg deur die metodenaam.

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

Soveel vir inkapseling, nè?

In elk geval, ek het altyd gehoor Python ondersteun nie inkapseling nie, so hoekom selfs probeer?Wat gee?

Was dit nuttig?

Oplossing

Die naam skommeling word gebruik om te verseker dat subklasse nie per ongeluk ignoreer die private metodes en eienskappe van hul superclasses. Dit is nie bedoel om doelbewuste toegang van buite te voorkom.

Byvoorbeeld:

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

Natuurlik, dit breek as twee verskillende klasse het dieselfde naam.

Ander wenke

Voorbeeld van private funksie

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

Toe ek die eerste keer van Java na Python I gekom het gehaat hierdie.Dit het my doodgeskrik.

Vandag is dit dalk net die een ding Ek is lief vir die meeste oor Python.

Ek hou daarvan om op 'n platform te wees waar mense mekaar vertrou en nie voel dat hulle ondeurdringbare mure rondom hul kode moet bou nie.In sterk ingekapsuleerde tale, as 'n API 'n fout het, en jy het uitgepluis wat verkeerd gaan, kan jy dalk steeds nie om dit werk nie, want die nodige metode is privaat.In Python is die houding:"seker".As jy dink jy verstaan ​​die situasie, dalk het jy dit selfs gelees, dan is al wat ons kan sê "sterkte!".

Onthou, inkapseling hou nie eers swak verband met "sekuriteit" of om die kinders van die grasperk af te hou nie.Dit is net nog 'n patroon wat gebruik moet word om 'n kodebasis makliker te verstaan.

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

  

Streng gesproke, private metodes is   toeganklik buite hul klas, net   nie maklik toeganklik. niks in   Python is werklik private; intern,   die name van private metodes en   eienskappe is verminkte en unmangled   on the fly om hulle te laat lyk   ontoeganklik deur hul name. jy   toegang tot die __parse metode van die   MP3FileInfo klas met die naam   _MP3FileInfo__parse. Erken dat dit 'n interessante, dan belowe om   nooit, ooit doen dit in real-kode.   Private metodes is privaat vir 'n   Daarom, maar soos baie ander dinge in   Python, hul privateness is   uiteindelik 'n kwessie van konvensie, nie   krag.

Die frase wat algemeen gebruik word, is "ons almal toestemmende volwassenes hier". Deur prepending 'n enkele underscore (nie bloot) of dubbel onderstreep (versteek), jy vertel die gebruiker van jou klas wat jy van plan is die lid aan 'n private 'wees in een of ander manier. Maar, jy vertrou almal om verantwoordelik op te tree en respek wat, tensy hulle 'n dwingende rede om nie te (bv debug gers, kode voltooiing).

As jy werklik moet iets wat private hê, dan kan jy dit implementeer in 'n uitbreiding (bv in C vir CPython). In die meeste gevalle, egter, jy net leer die Pythonic manier van dinge doen.

Dit is nie soos jy Absolutly kan nie rond privateness van lede kry in enige taal (wyser afreken in C ++, Reflections in NET / Java).

Die punt is dat jy 'n fout as jy probeer om die private metode roep per ongeluk. Maar as jy wil om jouself in die voet skiet, gaan voort en doen dit.

Edit: Jy moenie probeer om jou goed te beveilig deur OO-enkapsulasie, doen jy

Die class.__stuff naamkonvensie kan die programmeerder weet hy is nie bedoel om toegang __stuff van buite. Die naam mangling maak dit onwaarskynlik iemand sal dit doen deur 'n ongeluk.

Dit is waar, jy kan nog steeds werk om hierdie, is dit nog makliker as in ander tale (wat BTW ook laat jy dit doen), maar geen Python programmeerder sal dit doen as hy is besorg oor die inkapseling.

Soortgelyke gedrag bestaan ​​wanneer module-kenmerkname met 'n enkele onderstreep begin (bv._foo).

Module-kenmerke wat as sodanig genoem word, sal nie na 'n invoermodule gekopieer word wanneer die from* metode, bv.:

from bar import *

Dit is egter 'n konvensie en nie 'n taalbeperking nie.Dit is nie private eienskappe nie;hulle kan deur enige invoerder verwys en gemanipuleer word.Sommige argumenteer dat Python as gevolg hiervan nie ware inkapseling kan implementeer nie.

Dit is net een van daardie taal ontwerp keuses. Op 'n sekere vlak is dit geregverdig. Hulle maak dit dus moet jy mooi ver gaan uit jou pad om te probeer en noem die metode, en as jy dit regtig nodig het dat sleg, jy moet 'n goeie rede het!

Ontfouting hakies en toetsing kom na vore as moontlik aansoeke, gebruik 'n verantwoordelike natuurlik.

Met Python 3.4 is dit die gedrag:

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

  

Let daarop dat die mangling reëls meestal is ontwerp om ongelukke te vermy; dit nog moontlik is om toegang te verkry of te verander 'n veranderlike wat private beskou. Dit kan selfs nuttig in spesiale omstandighede, soos in die debugger wees.

Selfs al is die vraag ou Ek hoop my brokkie kan nuttig wees.

Die belangrikste bekommernis oor private metodes en eienskappe is om ontwikkelaars te vertel om dit nie buite die klas te noem nie en dit is inkapseling.'n mens kan sekuriteit van inkapseling verkeerd verstaan.wanneer 'n mens doelbewus sintaksis gebruik soos wat jy genoem het, wil jy nie inkapseling hê nie.

obj._MyClass__myPrivateMethod()

Ek het van C# af gemigreer en aanvanklik was dit vir my ook vreemd, maar na 'n rukkie het ek tot die idee gekom dat slegs die manier waarop Python-kode-ontwerpers oor OOP dink, anders is.

  

Hoekom is Python se "privaat" metodes nie eintlik private?

Soos ek dit verstaan, hulle kan nie wees private. Hoe kon privaatheid afgedwing word?

Die voor die hand liggende antwoord is "private lede kan slegs verkry word deur middel van self", maar dit sou nie werk nie - self is nie spesiaal in Python, dit is niks meer as 'n algemeen-gebruikte naam vir die eerste parameter van 'n funksie.

Gelisensieer onder: CC-BY-SA met toeskrywing
Nie verbonde aan StackOverflow
scroll top