Heim > Artikel > Backend-Entwicklung > Eine kurze Diskussion über die Lese- und Schreibberechtigungen von Python-Objektdaten
Objektorientierte Programmiersprachen sind beim Schreiben großer Programme oft bequemer und sicherer zu verwenden als prozessorientierte Sprachen. Einer der Gründe ist: Klassenmechanik. Die Klasse
klassifiziert und kapselt zahlreiche Daten und macht aus einem Datenobjekt ein vollständiges Individuum, nah am wirklichen Leben und hochgradig abstrakt. Die Kapselung von Klassen durch Python ist jedoch nicht gut, da alle Attribute und Methoden öffentlich sind und Sie nach Belieben darauf zugreifen oder schreiben können. Sie können die Attribute der Klasse außerhalb der Klasse ändern oder sogar Attribute hinzufügen. Das ist in der Tat beunruhigend.
Das Folgende ist eine Zusammenfassung der Lösungen nach dem Lernen.
1. Verwenden Sie 2 Unterstrich-Präfixe, um Eigenschaften oder Methoden auszublenden.
__xxx #!/usr/bin/python3 #-*- coding:utf-8 -*- class Student: def __init__(self,name,score): self.name = name self.__score = score #将score隐藏起来,使之仅在类内部可用。 def __show(self): #一个隐藏的方法,同样只在内部可用 print(self.name,self.__score)#使用被隐藏的属性__score def Show(self): self.__show() #注意被隐藏方法的调用方式。 def main(): he = Student('Bob',95) he.Show() #显示:Bob 95 #print(he.__score) #AttributeError: 'Student' object has no attribute '__score' #he.__show() #AttributeError: 'Student' object has no attribute '__show' #隐藏属性真的被隐藏了吗?其实仍然可使用,使用格式 obj._className__attributeName #但是仅仅作为了解,不建议使用隐藏属性。 print(he._Student__show()) #显示:Bob 95 print(he._Student__score) # 显示: 95 if __name__=="__main__": main()
Die Auswirkung doppelter Unterstriche auf Klassenattribute:
1. Stellen Sie sicher, dass die Attribute nur intern innerhalb dieser Klasse verwendet werden und nicht direkt von externen Klassen oder Unterklassen gelesen oder geändert werden können.
2. Die Attribute von Klassen, die _ _ verwenden, werden während der Implementierung umbenannt. Beispielsweise wird __age in der Klasse schließlich zu _A__age (Namensumstrukturierung). Dieser Vorteil ist: Es wird normalerweise zum Einbinden verwendet in der geerbten Elternklasse. Dadurch wird vermieden, dass Eigenschaften von Unterklassen überschrieben werden.
2. Erstellen Sie überschaubare Attribute.
Manchmal müssen wir das Schreiben von Attributen zusätzlich überprüfen, das Schreiben unzulässiger Werte ablehnen und Ausnahmen auslösen.
#!/usr/bin/python3 #-*- coding:utf-8 -*- class Student: def __init__(self,name,score): self.name = name self.score = score @property #实现属性的读取方法,读取实例的score值时,就会调用这个函数 def score(self): return self.__score @score.setter #实现属性写入方法,写入实例的score属性时,调用这个函数 def score(self,newVal): if not isinstance(newVal,(int,float)): raise TypeError('score value must be a number') if newVal>100 or newVal<0: raise ValueError('score value must between 0 and 100') self.__score = newVal def main(): he = Student('Bob',95) he.score = 100 #重新写入 print(he.score) #读取 if __name__=="__main__": main()
Wir können feststellen: self.__score ist der Ort, an dem der Attributwert tatsächlich gespeichert wird, und self.score ist eine Funktion (aber es Wird wie eine Eigenschaft verwendet und ist eine Methode zum Abrufen und Schreiben von Eigenschaftswerten.
Die mit socre.setter dekorierte Funktion wird auch während der Initialisierung aufgerufen, da der Aufruf von self.score unter der Funktion __init__() erscheint
Da self.__score nur zum Referenzieren des Werts verwendet wird Kann das Attribut mit einem anderen Namen benannt werden? Zum Beispiel saveScore... Natürlich ist es möglich, aber es ist „offengelegt“ und wir möchten nicht, dass es extern verfügbar ist. Wir sollten __ hinzufügen, um es auszublenden und versehentliche Änderungen zu verhindern.
Wenn Sie sicher sind, dass eine bestimmte Klasse keine Vererbung beinhaltet, können Sie die obige doppelte Unterstreichung in eine einzelne Unterstreichung umschreiben. Einerseits wird dadurch zwar nicht der versteckte Effekt erzielt nicht Löst den Namensverstümmelungsmechanismus aus,
, um Aufregung zu vermeiden. Andererseits kann das Beginnen mit einem Unterstrich Benutzer daran erinnern, dass dieses Attribut nicht direkt verwendet werden sollte. Dann kommt es auf das Selbstbewusstsein an.
Ein Instanzobjekt kann nach Belieben extern Attribute hinzufügen.#!/usr/bin/python3 #-*- coding:utf-8 -*- class Student: def __init__(self,name,score): self.name = name self.score = score def main(): he = Student('Bob',95) he.age = 19 print(he.age) if __name__=="__main__": main() 使用__slots__ #!/usr/bin/python3 #-*- coding:utf-8 -*- class Student: __slots__ = ('name','score') #将属性名以字符串形式加入元组 def __init__(self,name,score): self.name = name self.score = score def main(): he = Student('Bob',95) he.age = 19 #AttributeError: 'Student' object has no attribute 'age' print(he.age) if __name__=="__main__": main()
Auf diese Weise werden die Eigenschaften des Objekts auf das Innere der Klasse beschränkt.
Aber __slots__ können nicht vererbt werden. Darüber hinaus besteht die ursprüngliche Entwurfsabsicht von __slots__ nicht in der oben genannten Verwendung, sondern in der Optimierung der Speichernutzung beim Erstellen einer großen Anzahl (Zehntausende) von Objekten.
Zusammenfassung: Nachdem ich dies geschrieben habe, stelle ich fest, dass die oben genannten Techniken von geringer Bedeutung sind. Der Designer der Klasse ist der Programmierer selbst, und der Benutzer ist auch er selbst, daher sollte das
Lesen und Schreiben der Objektattribute von ihm selbst gesteuert werden. Das Klassendesign selbst benötigt nicht zu viel Schutzcode. Andernfalls wird es aufgebläht und die Effizienz verringert. Schutzmaßnahmen sollten außerhalb der Klasse erfolgen, damit die vom Klassenobjekt empfangenen Daten immer legal sind, was leichter und flexibler ist. So fühle ich mich.
Der obige Artikel, in dem die Lese- und Schreibberechtigungen von Python-Objektdaten kurz erläutert werden, ist der gesamte vom Herausgeber geteilte Inhalt. Ich hoffe, dass er Ihnen eine Referenz geben kann, und ich hoffe auch, dass Sie dem mehr Aufmerksamkeit schenken Chinesische PHP-Website.
Weitere Artikel zu den Lese- und Schreibberechtigungen von Python-Objektdaten finden Sie auf der chinesischen PHP-Website!