객체 지향 프로그래밍 언어는 대규모 프로그램을 작성할 때 프로세스 지향 언어보다 사용하기 더 편리하고 안전한 경우가 많습니다. 그 이유 중 하나는 클래스 역학입니다.
클래스는 수많은 데이터를 분류하고 캡슐화하여 데이터 개체를 실제 생활에 가깝고 매우 추상적인 완전한 개체로 만듭니다. 그러나 Python의 클래스 캡슐화는 좋지 않습니다. 모든 속성과 메서드가 공개되어 있고 클래스 외부에서 클래스 속성을 수정하거나 속성을 추가할 수도 있기 때문입니다. 이것은 참으로 불안하다.
학습 후 해결 방법을 요약하면 다음과 같습니다.
1. 속성이나 메소드를 숨기려면 밑줄 접두사 2개를 사용하세요.
__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()
클래스 속성에 이중 밑줄이 미치는 영향:
1. 이 클래스 내에서만 사용되는 속성을 만들고 외부 또는 하위 클래스에서 직접 읽거나 수정할 수 없습니다.
2. _ _을 사용하는 클래스의 속성은 구현 중에 이름이 변경됩니다. 예를 들어 클래스의 __age는 결국 _A__age(이름 재구성)가 됩니다. 상속받은 부모 클래스. 이렇게 하면 하위 클래스 속성에 의해 재정의되는 것을 방지할 수 있습니다.
2. 관리 가능한 속성을 만듭니다.
때로는 속성 쓰기에 대한 추가 확인을 수행하고, 잘못된 값 쓰기를 거부하고, 예외를 발생시켜야 합니다.
#!/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()
찾을 수 있습니다: self.__score는 속성 값이 실제로 저장되는 위치이고 self.score는 함수입니다(그러나 사용됨). 속성과 마찬가지로 속성 값을 가져오고 쓰는 방법입니다.
초기화 중에 socre.setter 장식 함수도 호출됩니다. 왜냐하면 self.score 호출이 __init__() 함수 아래에 나타나기 때문입니다.
self.__score는 값을 참조하는 데만 사용되기 때문입니다. 속성의 이름을 다른 이름으로 지정할 수 있나요? saveScore와 같은... 물론 가능하지만 "노출"되어 외부에서 사용할 수 없도록 __을 추가하여 실수로 수정되는 것을 방지해야 합니다.
때때로 특정 클래스가 상속을 포함하지 않을 것이라고 확신하는 경우 위의 이중 밑줄을 단일 밑줄로 다시 작성할 수 있지만, 한편으로는 숨겨진 효과를 얻을 수 없습니다. not 소란을 피하기 위해
이름 변경 메커니즘을 실행합니다. 반면에 밑줄로 시작하면 이 속성을 직접 사용해서는 안 된다는 점을 사용자에게 상기시킬 수 있습니다. 그렇다면 그것은 자기 인식에 달려 있습니다.
인스턴스 객체는 마음대로 외부에서 속성을 추가할 수 있습니다.#!/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()
이와 같이 객체의 속성은 클래스 내부로 제한됩니다.
그러나 __slots__은 상속될 수 없습니다. 게다가 __slots__의 원래 설계 의도는 위의 사용법이 아니라, 많은 수(수만)의 객체를 생성할 때 메모리 사용량을 최적화하는 것입니다.
요약: 이 글을 쓰고 보니 위의 기술은 별 의미가 없다는 것을 알게 되었습니다. 클래스의 디자이너는 프로그래머 자신이고, 사용자도 자신이므로
객체 속성의 읽기 및 쓰기는 스스로 제어해야 합니다. 클래스 디자인 자체에는 많은 보호 코드가 필요하지 않습니다. 그렇지 않으면 부풀어 오르고 효율성이 감소합니다. 보호 조치는 클래스 외부에서 이루어져야 클래스 객체가 수신한 데이터가 항상 합법적이므로 더욱 가볍고 유연해집니다. 내 기분은 이렇다.
파이썬 객체 데이터의 읽기 및 쓰기 권한에 대해 간략하게 설명한 위의 글은 모두 편집자가 공유한 내용이므로 참고가 되셨으면 좋겠습니다. PHP 중국어 웹사이트.
Python 객체 데이터의 읽기 및 쓰기 권한에 대한 더 많은 기사를 보려면 PHP 중국어 웹사이트를 주목하세요!