우리는 앞에서 클래스 안에 인스턴스 변수나 메소드들을 정의하였습니다. 이들 변수나 메소드들은 누구나 사용할 수 있는 것처럼 설명하였습니다.
하지만 이렇게 하는 것이 좋은 것일까요? 예를 들어서 학생을 나타내는 Student 클래스를 살펴봅시다.
class Student:
def __init__(self, name=None, age=0):
self.name = name
self.age = age
obj = Student("Hong", 20)
obj.age = 21
print(obj.age)
<실행 결과>
21
위의 코드에서는 객체 s의 변수 age에 마음대로 접근하여서 값을 변경할 수 있었습니다.
하지만 이런 식으로 마음대로 인스턴스 변수의 값을 변경하는 것은 다음과 같은 이유에서 좋은 방법이 아닙니다.
obj.age = -10 # 학생의 나이가 -10?
클래스 외부에서 age를 마음대로 사용하고 있었다면 이것 또한 불가능합니다.
class Student:
def __init__(self, name=None, birthday="20010611"):
self.name = name
self.birthday = birthday
객체 지향 방법의 개념 중에 정보 은닉(information hiding)이 있습니다. 정보 은닉이란 구현의 세부 사항을 클래스 안에 감추는 것입니다.
대표적인 것이 클래스 안의 데이터를 외부에서 마음대로 변경하지 못하게 하는 것입니다. 따라서 클래스 안에 변수를 선언할 때는 private 으로 만드는 것이 좋습니다.
private 변수로 만들면 외부로부터의 접근이 차단됩니다. 클래스는 변수는 안에 감추고 외부에서는 메소드들만 사용하도록 설계하는 것이 좋다고 합니다.
파이썬에서 인스턴스 변수를 private으로 정의하려면 변수 이름 앞에 __을 붙이면 됩니다.
private이 붙은 인스턴스 변수는 클래스 내부에서만 접근될 수 있습니다. 예를 들어서 Student 클래스 안의 인스턴스 변수들을 private으로 정의하면 다음과 같습니다.
class Student:
def __init__(self, name=None, age=0):
self.__name = name
self.__age = age
obj = Student()
print(obj.__age)
<실행 결과>
AttributeError: 'Student' object has no attribute '__age'
위의 코드에서 __age는 private 변수이므로 오류가 발생합니다.
클래스의 멤버에 대한 접근을 제어하는 것은 객체 지향 프로그래밍의 중요한 부분입니다. 접근을 제어하게 되면 객체를 잘못 사용하는 것을 방지할 수 있습니다.
올바르게 정의된 메소드만 데이터를 사용할 수 있게 하면 데이터의 값이 부적절한 값으로 변경되는 것을 막을 수 있습니다.
예를 들어서 데이터의 범위를 검사하여서 범위를 벗어난 값이 멤버에 저장되는 것을 막을 수 있습니다.
지금까지는 변수만 가지고 접근 제어를 설명하였지만 메소드에 대해서도 똑같은 이야기를 할 수 있습니다.
메소드를 정의할 때도 앞에 __을 붙일 수 있고 그 의미는 변수의 경우와 동일합니다.
여기서는 일부 인스턴스 변수만을 private으로 정의하는데 모든 클래스의 인스턴스 변수를 private으로 정의하면 코드가 길어기조 설명이 복잡해지기 때문입니다.
실전 프로그래밍에서는 예기치 못한 오류를 막기 위해서 모든 인스턴스 변수들을 private으로 선언하는 것이 권장됩니다.