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)
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
Kiitoksia valaisevasta esimerkistä. Tästä olisi hyvä tehdä jatkoa python-ohjeelle, joka ei käsittele (vielä?) luokkia.
Aihe on jo aika vanha, joten et voi enää vastata siihen.