메뉴 닫기

파이썬 클래스 속성 접근 제한 방법 완벽 정리

파이썬 클래스 속성 접근 제한 방법 완벽 정리

🔐 private이 없는 파이썬에서 속성 보호하는 진짜 방법

파이썬은 다른 객체지향 언어처럼 private, protected 같은 접근 제한자를 명시적으로 제공하지 않습니다.
이 점이 처음 파이썬을 접하는 분들에겐 혼란스러울 수 있어요.
하지만 파이썬에서도 클래스 속성을 은닉하거나 외부에서 직접 접근하지 못하게 만드는 방법은 존재합니다.
대표적인 것이 바로 변수명 앞에 밑줄(언더스코어)을 붙이는 방식입니다.

이번 글에서는 파이썬에서 클래스 속성의 접근을 제한하는 다양한 방법을 하나하나 살펴보겠습니다.
단일 밑줄(_var), 이중 밑줄(__var), 그리고 네임 맹글링(name mangling)이 어떻게 동작하는지 실제 예제를 통해 알아보고,
다른 언어들과 어떤 차이가 있는지도 함께 비교해볼 거예요.
파이썬 클래스 설계 시 중요한 보안성과 캡슐화 개념을 함께 익혀봅시다.



🔗 파이썬은 왜 접근 제한자를 제공하지 않을까?

자바나 C++ 같은 객체지향 언어에는 private, protected, public처럼 접근 제한자를 명확하게 구분할 수 있는 키워드가 존재합니다.
이러한 키워드는 코드의 보안성과 유지보수성을 높이는 데 도움을 줍니다.
하지만 파이썬은 이러한 명시적인 접근 제어 키워드를 제공하지 않습니다.

그렇다고 파이썬이 보안이나 캡슐화를 중요하게 여기지 않는 건 아닙니다.
파이썬은 “우리는 성인이다(We are all adults here)”라는 개발 문화에 기반을 두고 있어요.
즉, 파이썬은 개발자가 코드를 의도대로 사용할 것이라고 신뢰하는 언어이며, 강제적인 제한보다는 “관례(convention)”를 통해 속성을 보호하는 방식을 택하고 있습니다.

예를 들어 클래스 내부 속성을 외부에서 직접 건드리지 않기를 바랄 때, 변수명 앞에 밑줄(_)을 붙이는 관례를 따릅니다.
이렇게 하면 해당 속성은 “내부에서만 사용해 주세요”라는 암묵적인 신호를 전달하게 됩니다.

💡 TIP: 파이썬에서 ‘접근 제한’은 법적인 강제성이 아니라 개발자 간의 신뢰를 바탕으로 한 약속입니다.

이런 철학 덕분에 파이썬은 다른 언어에 비해 더 간결하고 유연한 구조를 가질 수 있게 되었죠.
물론 필요한 경우에는 __double_underscore와 같은 이름 맹글링 기능으로 조금 더 강한 보호를 적용할 수도 있습니다.
이 부분은 다음 STEP에서 자세히 다루겠습니다.

🛠️ 단일 언더스코어로 비공개 속성 표현하기

파이썬에서 클래스 속성 이름 앞에 밑줄(_)을 하나 붙이는 방식은 “이 속성은 내부 용도로 사용하세요”라는 신호입니다.
이는 문법적인 제한이 아닌 관례(convention)에 기반한 표현이며, 실제로 접근이 차단되지는 않습니다.

예를 들어 다음과 같은 클래스가 있을 수 있습니다.

CODE BLOCK
class User:
    def __init__(self):
        self.name = "Alice"
        self._password = "1234"

u = User()
print(u.name)        # 출력: Alice
print(u._password)   # 출력: 1234 (접근 가능함)

위 예제에서 _password는 외부 접근을 제한하지는 않지만, “건드리지 마세요”라는 경고의 의미로 사용됩니다.
파이썬 개발자들은 이처럼 단일 밑줄이 붙은 속성은 건드리지 않는 것이 예의라는 약속을 따릅니다.

💎 핵심 포인트:
단일 언더스코어는 접근을 막지 않지만, 해당 속성이 내부 구현이라는 신호로 작동합니다.

또한, 단일 밑줄은 import 시에도 특별한 의미를 가집니다.
from module import * 구문을 사용할 때, 밑줄로 시작하는 속성은 자동으로 제외됩니다.
이는 해당 속성이 공개용 API가 아님을 명시하는 용도로도 활용됩니다.



⚙️ 이중 언더스코어와 네임 맹글링의 동작 원리

단일 언더스코어가 단순히 관례 수준의 접근 제한이라면, 이중 언더스코어(__)는 보다 강력한 보호 기능을 제공합니다.
파이썬은 이름 앞에 이중 밑줄이 붙은 속성에 대해 네임 맹글링(Name Mangling)을 자동으로 적용합니다.

이름 맹글링이란 해당 속성의 이름을 클래스 이름과 결합하여 내부적으로 _클래스명__속성명 형태로 변경하는 것을 말합니다.
이렇게 변경되면 외부에서 직접 해당 속성에 접근하기 어려워지므로, 사실상 private과 유사한 보호 기능을 갖게 됩니다.

CODE BLOCK
class Account:
    def __init__(self):
        self.__balance = 1000

acc = Account()
print(acc.__balance)  # AttributeError 발생

위 코드는 __balance 속성에 직접 접근하려고 시도하므로 AttributeError가 발생합니다.
하지만 실제로는 다음과 같이 내부에서 이름이 변경되어 저장되어 있습니다.

CODE BLOCK
print(acc._Account__balance)  # 출력: 1000

즉, 속성 이름이 변경되었을 뿐 실제 값은 존재하고 있으며 특정 방식으로 접근하면 여전히 사용이 가능합니다.
다만, 일반적인 코드에서는 이런 접근을 사용하지 않으며, 실수로 외부에서 속성이 덮어씌워지는 일을 방지하는 데 유용합니다.

⚠️ 주의: 네임 맹글링은 보안 장치가 아니라, 속성 이름이 의도치 않게 충돌하거나 수정되는 것을 막기 위한 ‘캡슐화 수단’입니다.

이처럼 이중 언더스코어를 통해 파이썬에서도 내부 속성을 보호하고, 외부 간섭을 최소화하는 객체지향적 코드를 작성할 수 있습니다.

🔌 파이썬 스타일의 캡슐화 접근법

캡슐화(encapsulation)는 객체지향 프로그래밍의 핵심 개념 중 하나입니다.
하지만 파이썬은 자바나 C++처럼 엄격하게 접근을 제한하지 않고, 개발자의 의도와 약속에 의존하는 방식으로 캡슐화를 구현합니다.

실제 개발에서는 내부 속성을 숨기기보다는 속성에 직접 접근하지 않도록 getter, setter 메서드를 정의하여 우회 접근을 유도하는 방식이 널리 사용됩니다.

CODE BLOCK
class User:
    def __init__(self):
        self.__email = ""

    def set_email(self, email):
        self.__email = email

    def get_email(self):
        return self.__email

u = User()
u.set_email("hello@example.com")
print(u.get_email())  # 출력: hello@example.com

이처럼 직접 속성에 접근하지 않고 간접 접근 방식을 사용하면, 나중에 내부 로직을 바꿔도 외부 코드에는 영향을 주지 않습니다.
이는 유지보수성과 유연성을 높이는 데 큰 도움이 되죠.

💎 핵심 포인트:
파이썬은 직접적인 강제보다 함수와 관례를 통해 객체의 무결성을 지키는 방식에 더 큰 비중을 둡니다.

또한 최근에는 @property 데코레이터를 활용하여 속성처럼 보이지만 실제로는 메서드를 사용하는 방식도 자주 활용됩니다.
이는 STEP 6에서 자세히 살펴보겠습니다.



💡 외부 접근을 완전히 차단할 수 있을까?

많은 분들이 궁금해하는 부분 중 하나가 바로 “파이썬에서 특정 속성을 외부에서 아예 접근 못하게 만들 수 있을까?”라는 점입니다.
정답부터 말씀드리면, 완전히 차단하는 방법은 없습니다.
파이썬은 원천적으로 보안 언어가 아니며, 모든 것은 우회 가능하다는 점을 전제로 설계되어 있기 때문입니다.

하지만 속성에 대한 제어권을 가지면서도 유연한 사용을 돕는 기능으로 @property 데코레이터가 널리 사용됩니다.
이 기능은 속성처럼 보이지만 내부적으로는 메서드로 동작해, 읽기 전용 속성 또는 검증 로직을 포함한 접근제어를 구현할 수 있습니다.

CODE BLOCK
class Product:
    def __init__(self, price):
        self.__price = price

    @property
    def price(self):
        return self.__price

    @price.setter
    def price(self, value):
        if value < 0:
            raise ValueError("가격은 음수가 될 수 없습니다.")
        self.__price = value

item = Product(10000)
print(item.price)  # 출력: 10000
item.price = 8000  # 정상
item.price = -1    # ValueError 발생

이처럼 @property를 사용하면 변수처럼 보이는 인터페이스를 유지하면서도 내부에서는 완벽하게 제어된 로직을 구현할 수 있습니다.

  • 🧩속성처럼 보이게 유지하면서도 내부 로직 분리 가능
  • 🛡️값 변경 시 유효성 검사 등 보안 강화 가능
  • 🔒읽기 전용 속성 구현에도 효과적

결론적으로, 파이썬은 속성을 완전히 봉쇄하는 방식보다는 합리적인 수준에서 제어하고, 개발자의 책임에 맡기는 철학을 따릅니다.
그 덕분에 더 유연하고 깔끔한 객체지향 프로그래밍이 가능하다는 장점도 함께 가져갑니다.

자주 묻는 질문 (FAQ)

파이썬에는 왜 private 키워드가 없나요?
파이썬은 개발자의 책임을 신뢰하는 철학을 따르기 때문에, 강제적인 접근 제한 대신 관례에 기반한 설계를 유도합니다.
언더스코어 하나와 두 개의 차이는 무엇인가요?
단일 밑줄은 내부 사용 권고를 의미하며, 이중 밑줄은 네임 맹글링을 통해 외부 접근을 어렵게 만듭니다.
이중 언더스코어를 사용해도 접근이 가능하던데요?
네임 맹글링된 속성은 내부적으로 이름이 변경된 것뿐이며, 특정 규칙을 통해 우회 접근이 가능합니다.
import * 할 때 언더스코어가 붙은 변수는 왜 제외되나요?
파이썬은 언더스코어로 시작하는 이름을 내부 구현으로 간주하여 자동으로 import 대상에서 제외합니다.
@property를 쓰면 어떤 점이 좋나요?
속성처럼 보이게 하면서도 내부에서는 메서드처럼 제어할 수 있어, 유효성 검사나 읽기 전용 처리에 유용합니다.
파이썬에서도 정말 private하게 만들 수는 없나요?
완벽한 차단은 불가능하지만, 네임 맹글링과 @property 등을 조합하면 외부 접근을 어렵게 만들 수 있습니다.
자바나 C++에서의 private과 파이썬은 어떻게 다르죠?
자바나 C++은 컴파일 단계에서 접근을 차단하지만, 파이썬은 실행 시점에서도 우회가 가능하도록 설계되어 있습니다.
파이썬 속성을 보호하는 가장 좋은 방법은 무엇인가요?
단일/이중 언더스코어, 네임 맹글링, @property 등을 상황에 맞게 적절히 조합하는 것이 가장 바람직한 방법입니다.

🧭 파이썬 속성을 안전하게 다루기 위한 실전 가이드

파이썬은 명시적인 접근 제한자 없이도 객체지향적인 속성 보호가 가능합니다.
언더스코어 한 개는 관례적으로 ‘내부용’ 속성이라는 신호를 보내고, 이중 언더스코어는 네임 맹글링을 통해 보다 강한 은닉을 구현합니다.
또한 @property를 활용하면 속성처럼 보이지만 내부적으로는 메서드를 통해 값의 접근과 변경을 통제할 수 있습니다.

이 글에서는 파이썬이 왜 private 키워드를 제공하지 않는지, 언더스코어의 의미, 네임 맹글링의 원리, 그리고 캡슐화 구현 방식까지 단계적으로 살펴보았습니다.
파이썬의 유연한 철학은 ‘막는 것’보다 ‘신뢰하고 경고하는 것’에 초점을 둡니다.
클래스 설계 시 이러한 철학을 바탕으로 개발자 간의 약속을 명확히 하고, 필요한 경우에는 @property나 네임 맹글링을 적절히 활용해보세요.


🏷️ 관련 태그 : 파이썬접근제한, 클래스속성보호, 파이썬언더스코어, 네임맹글링, 파이썬property, 캡슐화예제, 객체지향기초, 파이썬private, 파이썬클래스설계, 파이썬코딩습관