파이썬 - 클래스 - 2. 비공개변수
지난번 포스팅에서 파이썬의 클래스에 대해 설명했었다.
이번에는 속성과 메서드의 종류에 대해 설명해보고자 한다.
1. 클래스와 인스턴스의 속성의 상속
1. 상속 방법
앞에서 배웠던 내용을 정리해보면,
인스턴스나 클래스에서 속성을 사용할 때는 인스턴스 -> 클래스 -> 부모클래스 -> 조상클래스까지 순서대로 조회하면서, 찾는 이름의 속성이 나오는 순간 다음으로 넘어가지 않고 사용한다.
2. 동일한 속성, 다른 값
그런데 만약 동일한 이름의 속성을 사용하고 싶다면 어떻게 해야할까?
예를 들어, class 학교
상속하는 class 학생
이 있다면, 학교에도 name
이 있고 학생도 name
이 있을 것이다. 이 때, 학생의 instance에서 이름을 사용하려면 intstance.name="KIM"
을 선언하면 되지만, 그러면 해당 instance는 학교의 name을 사용하지 못하게 된다. (덮어쓰기가 되므로)
class School :
name = "청담중학교"
class Student(School):
name = "학생이름"
이렇게 속성이 중복되는 경우에 학교의 이름과 학생의 이름을 구분짓고 싶을 것이다.
이럴 때 첫번째 해결방법은, 각 클래스마다 속성이름을 다르게 짓는 것이다.
class School :
name_school = ""
class Studnet(School) :
name_student = ""
두번째 해결 방법은, 맹글링(mangling)을 사용하는 방법이다.
3. 비공개변수
대부분의 파이썬 코드에서 따르는 규약이 있다.
밑줄로 시작하는 이름 (예를 들어, _name)은 API의 비공용 부분으로 취급되어야 한다.
그 이름의 데이터타입이 무엇이던 상관없이 그러하다. (함수/메서드, 속성/변수)
밑줄로 시작하는 이름은 구현 세부/상세사항으로 취급되고, 예고없이 변경될 수 있다.
이 비공개 변수를 사용하면, 서브클래스와 비공개 변수의 충돌을 피할 수 있다.
이렇게 쉽고 유효한 수단이 있기 때문에, 파이썬에서는 이름이 뒤섞이는 것에 대한 기술적인 지원을 별로 하지 않는다.
(*네임 맹글링 : name mangling - 변수이름에 _
를 섞어서 짓이겨 버리기.)
(* 다른 언어와 달리, 파이썬에는, 객체 내에서만 액세스(접근)가능한, 비공개 인스턴스 변수가 존재하지 않는다.)
맹글링의 사용 사례를 몇개 찾아보자.
- 평범한 코드
class School :
def __init__(self) :
self.name = "청담중학교"
self.loc = "서울"
self.born = "1990년 1월 15일"
school = School()
print(school.name, school.loc, school.born)
# 청담중학교 서울 1990년 1월 15일
- 맹글링을 사용한 코드
class School :
def __init__(self) :
self.name = "청담중학교"
self.loc = "서울"
self.__born = "1990년 1월 15일"
school = School()
print(school.name, school.loc, school.__born)
# AttributeError: 'School' object has no attribute '__born'
여기에서 특이한 점은, 속성 born 앞에 __를 붙였을 뿐인데 같은이름으로 호출하면 에러가 발생한다는 것이다.
이를 보면, 맹글링을 적용하면
1. 하위클래스가 상위클래스의 속성을 덮어쓰거나
2. 하위클래스에서 동일한 이름을 사용할 수 있다.
4. 비공개변수에 접근하는 방법
맹글링을 통해서 '비공개처리'를 한다고 했는데, 그러면 이 데이터에 접근할 수 있는 방법은 없을까? 인스턴스와 클래스에 dir()을 사용해서 어떤 차이가 있는지 살펴보자.
class School :
def __init__(self) :
self.name = "청담중학교"
self.loc = "서울"
self.__born = "1990년 1월 15일"
school = School()
print(dir(School))
['__class__', '__delattr__', '__dict__', '__dir__','__doc__' ...]
print(dir(school))
['_School__born', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', ...
'loc', 'name']
코드를 보면, 인스턴스에는 'name', 'loc'뿐만이 아니라 '_School__born' 이라는 속성이 생긴것을 알 수 있다. 즉, 파이썬의 비공개변수
는 접근을 조금 더 까다롭게 만들 뿐이지, 아예 접근하지 못하도록 하는 방법은 없다.
5. 접근주의
정리하자면 Python 에서는 Information Hiding (정보은닉) 기능은 존재하지 않는다.하지만, __
(double underscore)를 통해 “접근금지” 라는 의사표현을 Name Mangling 을 통해 가능하다.
그렇다면 _
를 하나만 넣으면 어떨까?
변수 앞에
_
를 하게되면, 접근을 자제하라는 경고, (자바의 protected 제한자와 유사)
__
는 강한 접근 거부 의사를 표현하는 것이라고 볼 수 있다. (자바의 private 제한자와 유사)
😳 그렇다면 __init__ , __str__ 등은 보호되는건 아닌데 뭘까? 정답을 찾지 못했다...
6. 정리
위의 비공개 변수 처리는 속성 뿐만이 아니라 메서드에서도 동일하게 적용된다.
여기까지 우리는 파이썬에서, 클래스가 상속해줄 때, 숨기고 싶은 데이터의 처리는 \_
또는\_\_
를 사용하면 된다는 것을 알게되었다.
class Test :
def __hello(self) :
print("hello")
test2 = Test()
test2.__hello()
#AttributeError: 'Test' object has no attribute '__hello'
print(dir(test2))
['_Test__hello', '__class__', '__delattr__', '__dict__',...]
Author And Source
이 문제에 관하여(파이썬 - 클래스 - 2. 비공개변수), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@nzlk112/파이썬-클래스-2.-비공개변수저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)