Maison > Article > développement back-end > Une brève discussion sur les autorisations de lecture et d'écriture des données d'objet Python
Les langages de programmation orientés objet sont souvent plus pratiques et plus sûrs à utiliser que les langages orientés processus lors de l'écriture de programmes volumineux. L’une des raisons est : la mécanique de classe. La classe
classe et encapsule de nombreuses données, faisant d'un objet de données un individu complet, proche de la vie réelle et hautement abstrait. Cependant, l'encapsulation des classes par Python n'est pas bonne, car tous les attributs et méthodes sont publics et vous pouvez accéder ou écrire à volonté. Vous pouvez modifier les attributs de la classe en dehors de la classe, ou même ajouter des attributs. C’est effectivement troublant.
Ce qui suit est un résumé des solutions après l'apprentissage.
1. Utilisez 2 préfixes de soulignement pour masquer des attributs ou des méthodes.
__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()
L'impact des doubles traits de soulignement sur les attributs de classe :
1. Faites en sorte que les attributs soient utilisés uniquement en interne dans cette classe et ne puissent pas être directement lus ou modifiés par des classes externes ou des sous-classes.
2. Les attributs des classes utilisant _ _ seront renommés lors de l'implémentation. Par exemple, __age dans la classe finira par devenir _A__age (réorganisation du nom). la classe parent héritée. Cela évite d'être remplacé par les propriétés de la sous-classe.
2. Créez des attributs gérables.
Parfois, nous devons effectuer des vérifications supplémentaires sur l'écriture des attributs, rejeter l'écriture de valeurs illégales et provoquer des exceptions.
#!/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()
Nous pouvons trouver : self.__score est l'endroit où la valeur de l'attribut est réellement stockée, et self.score est une fonction (mais elle Utilisé comme une propriété), c'est une méthode pour obtenir et écrire des valeurs de propriété.
La fonction décorée socre.setter sera également appelée lors de l'initialisation, car l'appel à self.score apparaît sous la fonction __init__()
Puisque self.__score n'est utilisé que pour référencer la valeur de l'attribut, peut-il être nommé par un autre nom ? Comme saveScore.... Bien sûr, c'est possible, mais il est "exposé" et nous ne voulons pas qu'il soit disponible en externe. Nous devrions
ajouter __ pour le masquer afin d'éviter toute modification accidentelle.
Parfois, si vous êtes sûr qu'une certaine classe n'impliquera pas d'héritage, vous pouvez alors réécrire le double soulignement ci-dessus en un seul soulignement, bien que cela n'obtienne pas l'effet caché, d'une part, cela le fera. not Déclenchera le mécanisme de modification du nom,
pour éviter de faire des histoires. Par contre, commencer par un trait de soulignement peut rappeler aux utilisateurs que cet attribut ne doit pas être utilisé directement. Ensuite, cela dépend de la conscience de soi.
Un objet instance peut ajouter des attributs en externe à volonté.
#!/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()
De cette façon, les propriétés de l'objet sont limitées à l'intérieur de la classe.
Mais __slots__ ne peut pas être hérité. De plus, l'intention de conception initiale de __slots__ n'est pas l'utilisation ci-dessus, mais l'optimisation de l'utilisation de la mémoire lors de la création d'un grand nombre (des dizaines de milliers) d'objets.
Résumé :
Après avoir écrit ceci, je trouve que les techniques ci-dessus ont peu d'importance. Le concepteur de la classe est le programmeur lui-même, et l'utilisateur est également lui-même, donc la
lecture et écriture des attributs de l'objet doit être contrôlée par lui-même. La conception de la classe elle-même n'a pas besoin de trop de code de protection, sinon, il sera gonflé et l'efficacité sera réduite. Les mesures de protection doivent avoir lieu en dehors de la classe, afin que les données reçues par l'objet de classe soient toujours légales, ce qui sera plus léger et flexible. C'est ce que je ressens.
L'article ci-dessus discutant brièvement des autorisations de lecture et d'écriture des données d'objet Python est tout le contenu partagé par l'éditeur. J'espère qu'il pourra vous donner une référence, et j'espère également que vous accorderez plus d'attention au. Site Web chinois PHP.
Pour plus d'articles sur les autorisations de lecture et d'écriture des données d'objets Python, veuillez faire attention au site Web PHP chinois !