Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: Python: Miten protected ja public eroavat python3:ssa?

peran [05.12.2021 17:37:15]

#

Elikkäs olen ymmärtänyt, että pythonissa public-muuttujat merkitään self.muuttuja1, protected-muuttujat merkitään self._muuttuja2 ja privaattimuuttujat self.__muuttuja3, mutta minulle ei ole selvinnyt, mitä toiminnallista eroa pythonissa on public-muuttujien ja protected-muuttujien välillä ?

Tässä vähän testejäni...

# Isäntä luokka
class Isanta:
     public1 = None
     _protected2 = None
     __private3 = None

     # constructori
     def __init__(self, m1, m2, m3):
          self.public1 = m1
          self._protected2 = m2
          self.__private3 = m3

     def displayPublicMembers(self):
          print("Public Data Member: ", self.public1)

     def _displayProtectedMembers(self):
          print("Protected Data Member: ", self._protected2)

     def __displayPrivateMembers(self):
          print("Private Data Member: ", self.__private3)

     def accessPrivateMembers(self):
          self.__displayPrivateMembers()

#Lapsi luokka
class Lapsi(Isanta):
    def __init__(self, m1, m2, m3):
        Isanta.__init__(self, m1, m2, m3)

    def accessProtectedMembers(self):
        self._displayProtectedMembers()

obj = Lapsi("Public", "Protected", "Private")

obj.displayPublicMembers()
obj.accessProtectedMembers()
obj.accessPrivateMembers()
print()
print("Object can access public member:",obj.public1)
obj._displayProtectedMembers()

print("Object is accessing protected member:", obj._protected2)

obj._varri="OK?"
print("obj._varri=",obj._varri)
print("Protected -> Protected Muutettu")
obj._protected2="Protected Muutettu"
obj.accessProtectedMembers()

# Tämä antaa odotetun mallisen virheilmoituksen.
#print(obj.__private3)

Metabolix [05.12.2021 19:42:16]

#

Pythonissa kahdella alaviivalla merkityt yksityiset muuttujat ovat näkyvissä vain saman luokan sisällä. Sen sijaan yhdellä alaviivalla merkityt ”suojatut” (protected) jäsenet ovat ihan yhtä julkisia kuin muutkin, ja niiden ero on täysin sopimuskysymys.

Olet edellä vielä sekoittanut pakkaa luokkamuuttujilla. Pythonissa jäsenmuuttujat pitää tehdä funktioiden sisällä (eli self.muuttuja), ja nuo luokan alun muuttujat ovat luokalle yhteisiä (kuten monessa kielessä static-sanalla määritellyt) ja niihin viitataan luokan nimen avulla.

Ehkä tämä selventää:

def debug(l):
	print(("%10s | " * len(l)) % l)

debug(("funktio", "A.x", "B.x", "self.x", "self._x", "self.__x"))
debug(("-"*10,) * 6)

class A:
	x = 'class A: x'
	def __init__(self):
		self.x = 'A-self.x'
		self._x = 'A-self._x'
		self.__x = 'A-self.__x'

	def print_a(self):
		debug(("print_a", A.x, "", self.x, self._x, self.__x))

class B(A):
	def __init__(self):
		A.__init__(self)
		self.x = 'B-self.x'
		self._x = 'B-self._x'
		self.__x = 'B-self.__x'

	def print_b(self):
		debug(("print_b", A.x, B.x, self.x, self._x, self.__x))

a = A()
a.print_a()
A.x = 'A.x'
a.x = 'a.x'
a._x = 'a._x'
a.__x = 'a.__x'
a.print_a() # A-self.__x ei ole muuttunut.
print(a.__x) # Näkyy erillinen ulkoinen a.__x.

b = B()
b.print_a() # Näkyy edellä muutettu A.x, normaali self.x ja A-luokan self.__x.
b.print_b() # Tässä B.x === A.x, erikseen on self.x, ja näkyy B-luokan self.__x.
B.x = 'B.x' # Tästä tulee uusi B.x, joka on eri kuin A.x.
b.x = 'b.x'
b._x = 'b._x'
b.__x = 'b.__x'
b.print_a() # Näkyy A-self.__x.
b.print_b() # Näkyy B-self.__x.
print(b.__x) # Näkyy erillinen ulkoinen b.__x.
   funktio |        A.x |        B.x |     self.x |    self._x |   self.__x |
---------- | ---------- | ---------- | ---------- | ---------- | ---------- |
   print_a | class A: x |            |   A-self.x |  A-self._x | A-self.__x |
   print_a |        A.x |            |        a.x |       a._x | A-self.__x |
a.__x
   print_a |        A.x |            |   B-self.x |  B-self._x | A-self.__x |
   print_b |        A.x |        A.x |   B-self.x |  B-self._x | B-self.__x |
   print_a |        A.x |            |        b.x |       b._x | A-self.__x |
   print_b |        A.x |        B.x |        b.x |       b._x | B-self.__x |
b.__x

peran [06.12.2021 16:35:59]

#

Kiitoksia valaisevasta esimerkistä. Tästä olisi hyvä tehdä jatkoa python-ohjeelle, joka ei käsittele (vielä?) luokkia.

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta