1. 접근 제어자란?
- 접근 제어자는 클래스와 클래스 멤버를 선언을 할 때 사용하는 제어자로 정보 은닉을 구현하기 위해 사용된다
- 정보 은닉을 이용하면 사용자는 내부의 구현은 신경 쓰지 않고 주어진 최소한의 정보(인터페이스)만을 이용해 프로그램을 사용할 수 있다
- 접근 제어자의 종류는 public, protected, private 가 있다
- python에서는 다른 객체지향 언어와 달리 실제로 접근을 막지 않는다
- python에서는 멤버 이름 앞에 언더바('_')를 이용해 접근 제어자 기능을 수행한다
- private > 2개의 언더바 사용(__)
- protected > 1개의 언더바 사용(_)
- public > 언더바 사용 x
2. 접근 제어자의 종류
1) private
- private member는 외부에 공개되지도 않고 외부에서 접근도 할 수 없다
- public method를 이용해 private member에 접근할 수 있다
- 외부에 공개되지 않고 클래스 내부에서 동작을 구현할 때 사용된다
- python에서는 '_class__private'으로 접근이 가능하다
2) public
- public member는 외부에 공개되며 같은 패키지, 다른 외부 패키지 어디서든 접근이 가능하다
- private member는 public method로 접근할 수 있다, 외부와의 인터페이스 역할을 한다
3) protected
- 상속의 개념이 사용되면 protected 제어자를 사용할 수 있다
- protected member는 부모 클래스에서는 public으로 외부에서는 private으로 취급된다
- python에서는 실질적으로 접근을 제어하지는 않고 '_'을 붙여 protected임을 명시(경고)하는 정도로만 사용된다
3) 접근 제어자의 사용
class Test1(object):
def __init__(self):
pass
def public(self):
print('public')
def _protected(self):
print('protected')
def __private(self):
print('private')
def access_from_out(self):
self.__private()
public은 별도의 접근제어자를 설정하지 않았으므로 외부에서 자유롭게 접근이 가능하다
__private은 내부에서는 접근 가능하지만 외부에서는 접근이 불가능하다
access_from_out은 내부에서 __private에 접근하고 있으므로 정상적인 접근이 가능하다
test1 = Test1()
try:
test1.public()
test1.access_from_out()
test1.__private()
except AttributeError:
print("can't access")
결과를 확인해보자
public
private
can't access
public method인 access_from_out을 이용하면 private에 접근이 가능하지만, 직접 private에 접근하면 AttributeError가 발생하게 된다
3. private member
다른 객체지향 언어와 달리 python은 외부에서도 private member에 접근이 가능하다. 클래스를 선언하고 dir을 확인하면 다음과 같다
print(dir(Test1()))
['_Test1__private', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_protected', 'access_from_out', 'public']
private으로 설정한 __private의 이름 앞에 _Test1이 붙어있는 것을 확인할 수 있다. python에서는 name mangling을 통해 private member의 이름을 바꿔줄 뿐 실제로 _Test1__private를 사용하면 외부에서도 접근이 가능하다
Test1()._Test1__private()
'Python > Syntax' 카테고리의 다른 글
[Python] sys.stdin.readline (0) | 2021.07.25 |
---|---|
[Python] List의 요소 삭제하기 (pop, remove, clear, del) (0) | 2021.06.27 |
[Python] List method 시간복잡도 (0) | 2020.10.12 |
[Python] 한 줄에 두 개의 정수 입력 받기 (input, map) (0) | 2020.09.08 |
[Python] split (0) | 2020.09.08 |