재산 접근 통제
앞서 언급했듯이 Python에는 실제 사유 속성이 없습니다. 그러면 Python 클래스의 캡슐화가 제대로 이루어지지 않습니다. 우리는 때때로 Python이 개인 속성을 정의한 다음 공개적으로 액세스 가능한 get 메서드와 set 메서드를 제공할 수 있기를 원합니다. Python은 실제로 매직 메소드를 통해 캡슐화를 달성할 수 있습니다.
Method | Description |
__getattr__(self, name) | 이 메서드는 존재하지 않는 속성에 액세스하려고 할 때의 동작을 정의합니다. 따라서 이 메서드를 오버로드하면 맞춤법 오류를 찾아 리디렉션하거나 더 이상 사용되지 않는 일부 속성에 대해 경고할 수 있습니다. |
__setattr__(self, name, value) | 은 속성을 할당하고 수정할 때의 동작을 정의합니다. 객체의 속성이 존재하는지 여부에 관계없이 속성에 대한 할당이 허용됩니다. 한 가지 주의할 점은 __setattr__을 구현할 때 "무한 재귀" 오류, |
__delattr__(self, name) | 을 피해야 한다는 것입니다. __delattr__ 및 _ _setattr__은 속성을 삭제할 때의 동작을 정의한다는 점을 제외하면 매우 유사합니다. __delattr__을 구현하는 것은 동시에 "무한 재귀" 오류를 방지하는 것입니다 |
__getattribute__(self, name) | __getattribute__는 속성에 액세스할 때의 동작을 정의합니다. 이에 비해 __getattr__은 속성이 존재하지 않는 경우에만 트리거됩니다. . 효과. 따라서 __getattribute__를 지원하는 Python 버전에서는 "무한 재귀" 오류를 방지하려면 __getattr__을 호출하기 전에 __getattribute__``__getattribute__를 호출해야 합니다. |
위 메소드 표에서 볼 수 있듯이 속성 접근 제어를 정의할 때 쉽게 오류가 발생할 수 있는데, 다음 예시를 보면 알 수 있습니다.
def __setattr__(self, name, value): self.name = value # 每当属性被赋值的时候, ``__setattr__()`` 会被调用,这样就造成了递归调用。 # 这意味这会调用 ``self.__setattr__('name', value)`` ,每次方法会调用自己。这样会造成程序崩溃。 def __setattr__(self, name, value): # 给类中的属性名分配值 self.__dict__[name] = value # 定制特有属性
위 메소드를 호출하는 구체적인 예시는 다음과 같습니다. 다음:
#!/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
출력 결과:
调用了 __setattr__ 方法 调用了 __getattribute__ 方法 调用了 __getattribute__ 方法 调用了 __getattr__ 方法 调用了 __delattr__ 方法