Contrôle d'accès à la propriété
Comme mentionné précédemment, Python n'a pas de véritables propriétés privées. Cela conduit alors à une mauvaise encapsulation des classes Python. Nous souhaitons parfois que Python soit capable de définir des propriétés privées, puis de fournir des méthodes get et set accessibles publiquement. Python peut réellement réaliser l'encapsulation grâce à des méthodes magiques.
Méthode | Description |
__getattr__(self, name) | Cette méthode définit le comportement lorsque vous essayez d'accéder à un attribut inexistant. Par conséquent, surcharger cette méthode peut détecter les fautes d’orthographe et les rediriger, ou avertir de certains attributs obsolètes. |
__setattr__(self, name, value) | définit le comportement lors de l'attribution et de la modification des attributs. Qu'un attribut de l'objet existe ou non, l'affectation à l'attribut est autorisée. Une chose à noter est que lors de l'implémentation de __setattr__, vous devez éviter l'erreur de "récursion infinie", |
__delattr__(self, name) | __delattr__ et _ _setattr__ sont très similaires, sauf qu'ils définissent le comportement lorsque vous supprimez un attribut. Implémenter __delattr__, c'est éviter les erreurs de "récursion infinie" en même temps |
__getattribute__(self, name) | __getattribute__ définit le comportement lors de l'accès à votre attribut. En comparaison, __getattr__ ne sera déclenché que lorsque l'attribut n'existe pas. . effet. Par conséquent, dans les versions Python qui prennent en charge __getattribute__, __getattribute__``__getattribute__ doit être appelé avant d'appeler __getattr__ pour éviter les erreurs de « récursivité infinie ». |
Comme vous pouvez le voir dans le tableau des méthodes ci-dessus, vous pouvez facilement provoquer une erreur lors de la définition du contrôle d'accès aux attributs. Vous pouvez jeter un œil à l'exemple suivant :
def __setattr__(self, name, value): self.name = value # 每当属性被赋值的时候, ``__setattr__()`` 会被调用,这样就造成了递归调用。 # 这意味这会调用 ``self.__setattr__('name', value)`` ,每次方法会调用自己。这样会造成程序崩溃。 def __setattr__(self, name, value): # 给类中的属性名分配值 self.__dict__[name] = value # 定制特有属性
L'exemple spécifique d'appel de la méthode ci-dessus est le suivant. suit :
#!/usr/bin/env python3 # -*- coding: UTF-8 -*- class User(object): def __getattr__(self, name): print('调用了 __getattr__ 方法') return super(User, self).__getattr__(name) def __setattr__(self, name, value): print('调用了 __setattr__ 方法') return super(User, self).__setattr__(name, value) def __delattr__(self, name): print('调用了 __delattr__ 方法') return super(User, self).__delattr__(name) def __getattribute__(self, name): print('调用了 __getattribute__ 方法') return super(User, self).__getattribute__(name) if __name__ == '__main__': user = User() # 设置属性值,会调用 __setattr__ user.attr1 = True # 属性存在,只有__getattribute__调用 user.attr1 try: # 属性不存在, 先调用__getattribute__, 后调用__getattr__ user.attr2 except AttributeError: pass # __delattr__调用 del user.attr1
Le résultat de sortie :
调用了 __setattr__ 方法 调用了 __getattribute__ 方法 调用了 __getattribute__ 方法 调用了 __getattr__ 方法 调用了 __delattr__ 方法