공개(Public) 변수란 무엇인가?
Python은 Java나 C++ 같은 언어와 달리, 변수 접근이나 메서드 호출을 문법적으로 강제하지 않습니다. 따라서 Python에서 모든 변수와 메서드는 기본적으로 공개(public) 상태입니다.
변수나 메서드를 공개하고 싶다면 특별한 작업을 할 필요가 전혀 없습니다. 그대로 선언하면 됩니다. 아래 예제를 살펴보겠습니다.
예제
class Mug:
def __init__(self):
self.color = None
self.content = None
def fill(self, beverage):
self.content = beverage
def empty(self):
self.content = None
brownMug = Mug()
brownMug.color = "brown"
print(brownMug.empty())
print(brownMug.fill('tea'))
print(brownMug.color)
print(brownMug.content)위 코드의 모든 변수(color, content)와 메서드(fill, empty)는 별도의 선언 없이도 클래스 외부에서 자유롭게 접근할 수 있습니다.
비공개(Private) 변수란 무엇인가?
데이터 멤버를 비공개(private)로 선언한다는 것은 클래스 외부에서는 누구도 해당 멤버에 접근할 수 없어야 한다는 의미입니다.
Python은 이를 위해 네임 맹글링(name mangling)이라는 기법을 지원합니다. 이 기능은 최소 두 개의 밑줄(__)로 시작하고 최대 하나의 밑줄로 끝나는 모든 멤버 이름을 _<클래스명><멤버명> 형태로 자동 변환합니다.
즉, 멤버를 비공개로 만들려면 변수 이름 앞에 밑줄 두 개(__)를 붙이기만 하면 됩니다. 아래 예제를 확인해 보겠습니다.
예제
class Cup:
def __init__(self, color):
self.__content = None # 비공개 변수
def fill(self, beverage):
self.__content = beverage
def empty(self):
self.__content = None이제 이 컵(Cup) 객체는 fill()과 empty() 메서드를 통해서만 내용물을 채우거나 비울 수 있습니다. 외부에서 __content에 직접 접근하려고 시도하면 AttributeError 오류가 발생합니다.
하지만 주의할 점이 있습니다. Python의 네임 맹글링은 완벽한 보안 장치가 아니기 때문에, 여전히 다음과 같이 우회하여 접근하는 것이 가능합니다.
redCup = Cup("red")
redCup._Cup__content = "tea" # 네임 맹글링 우회 접근이처럼 Python의 비공개 변수는 타 언어처럼 엄격하게 강제되는 접근 제한이라기보다는, "내부 구현이므로 외부에서 직접 사용하지 말라"는 개발자 간의 약속에 가깝습니다. 참고로 밑줄 하나(_variable)로 시작하는 변수는 관례상 protected(보호) 변수로 취급되며, 이 역시 문법적인 강제성은 없습니다.