[python] Name Mangling

gunny·2025년 2월 12일
0

Python

목록 보기
30/35

Name Mangling

  • python 에서 Name Mangling은 클래스 내부에서 사용되는 이름이 다른 이름으로 바뀌는 과정이다.
    주로 클래스 내부에서 변수나 메서드 이름을 외부에서 접근할 수 없도록 하기 위해 사용된다.
  • python은 기본적으로 모든 변수나 메서드 이름을 공개하지만, 이름 충돌을 피하기 위해 특별한 규칙을 적용할 수 있다.

Name Mangling 동작 방식

  • Python에서 클래스 내부에 __ 두개의 언더 스코어를 접두사로 사ㅛㅇ한 변수나 메서드는 name mangling을 겪는다.
    예를 들어 클래스 내부에서 __variable__ 로 정의된 변수는 실제로 클래스 외부에서는 _<클래스 이름> __variable 이라는 이름으로 변경된다.
class Myclass:
	def __init__(self):
    	self.__private = 42 # Name Mangling이 적용
        
    def __private(self):
    	print("This is a private method")
       
 obj = MyClass()
 
 # 외부에서 접근하려고 하면 에러 발생
 print(obj.__private) # AttributeError: 'MyClass' object has no attribute '__private'

# name mangling 된 이름으로 접근 가능
print(obj._MyClass__private) # 42

Name Mangling 규칙

  • __<name> 으로 정의된 변수는 실제로는 _<클래스 이름>__<name> 으로 변경된다.
  • 이는 상속을 통해 이름 충돌을 피하는데 유용하다.
  • __<name> 은 외부에서 직접 접근을 제한하기 위한 방법이지만, 여전히 접근할 수는 있다.

Name Mangling을 사용하는 이유

  • 이름 충돌 방지 : 상속 받은 클래스에서 부모 클래스의 변수나 메서드 이름이 충돌할 때 이를 피하기 위해 사용

  • 변수 보호 : __로 시작하는 이름은 Python에서 "비공개"로 간주되지만, 실제로 접근은 불가능하지 않기 때문에 단순히 "이름을 바꾸는" 방법으로 보호함.

  • 진정한 은닉을 원한다면 python은 그다지 강력한 보호를 제공하지 않고, 관습에 의존하는 방식임.

python에서 진정한 은닉(private)

  • python에서는 진정한 은닉(private)을 강제로 적용할 수 있는 방법은 기본적으로 제공되지 않는다.
  • 진정한 은닉을 위할 때는 몇 가지 방법을 고려할 수 있다.
  1. 이름 Mangling을 사용하데 강제로 접근 제한하기
  • __ (두 개의 언더스코어)는 이름 mangling을 통해 외부 접근을 어렵게 만든다. 이 접근 방식은 완벽하게 은닉되는 것은 아니라, 접근을 최소화하고 인터페이스를 통제화하는 방법이 더 중요하다.
class MyClass:
	def __init__(self):
    	self.__private = 42
      
    def get_private(self):
    	return self.__private

이렇게 하면 __private 변수에 대한 직접 접근을 막을 수 있지만 여전히 get_private 메서드를 통해 간접적으로 값을 얻을 수 있다.

  1. Property를 사용하여 접근 제어
  • 속성(property)을 사용해 객체 내부 데이터를 은닉하고, 필요한 경우에만 외부에 데이터를 반환하도록 한다. 이 방법은 외부에서 직접 접근을 막고, 메서드를 통해 데이터를 안전하게 제어한다.
class MyClass:
	def __init__(self):
    	self.__private= 42
    
    @property
    def private(self):
    	return self.__private
        
    @private.setter
    def private(self, value):
    	if value > 0:
        	self.__private = value
        else:
        	raise ValueError("Value must be positive")

이 방식은 객체 외부에서 직접 __private에 접근할 수 없게 하고, getter와 setter 메서드를 통해 값에 대한 접근을 제어할 수 있다.

  1. _private 와 같은 "약속된" 이름을 사용하여 보호
  • python에서 __ (두 개의 언더스코어)는 이름 mangling을 적용하지만, 실제로는 은닉을 제공하지 않기 때문에 _ (하나의 언더스코어)를 사용해 "비공개"로 취급하는 것이 일반적이다. 그러나 이는 완전한 은닉을 보장하지 않고 그저 관례이다.

class MyClass:
	def __init__(self):
    	self._private = 42 # 개발자 관례로 비공개 취급
  1. 외부에서 접근할 수 없는 클래스를 만드는 방법
  • 진정한 은닉을 원할 경우 클래스 외부에서 접근할 수 없는 클래스를 만드는 방식을 고려한다. 이 방식은 private 클래스를 다른 곳에서 접근할 수 없게 만들고, 클로저나 내부적으로 사용하도록 제한하는 방식이다.

class OuterClass:
	class _InnerClass:
    	def __init__(self):
        	self.__private = 42
    
    def __init__(self):
    	self._inner = self._InnerClass()
    
    def get_private(self):
    	return self._inner.__private # 외부에서 접근 불가

이 방식은 실용성보다는 특정한 환경에서만 유용할 수 있다.
(일반적인 객체 지향 프로그래밍에서는 잘 사용하지 않기 때문.
유용한 특정환경은 플로그인 시스템에서 모듈화된 구현을 숨기고 싶을때, 내부 API를 보호할때, 클로저(Closer)와 관련된 코드, 성능 최적화를 위한 내부 구현, 상속을 통한 의도적인 제한

진정한 은닉이 필요한 이유

[1] 캡슐화(Encapsulation) : 내부 구현 세부 사항을 숨기고, 객체의 상태를 안전하게 유지하며, 외부에서는 정의된 인터페이스만을 통해 상호작용할 수 있도록 하는 설계 원칙. 이를 통해서 객체의 상태를 외부에서 잘못 수정하거나, 예기치 않게 변경되는 것을 방지할 수 있다.

[2] 코드 유지보수 용이성 : 객체 내부의 구현을 은닉하면, 내부 구현이 변경되어도 외부 코드에 영향을 미치지 않게 된다. 이는 시스템의 확장성과 유지보수성을 높인다.

결론

Python은 기본적으로 모든 것이 "공개"라는 철학을 따르지만, Name mangling이나 다른 기법을 통해 의도적으로 은닉할 수 있다. 그러나 Python의 은닉은 철저하지 않기 때문에, 진정한 은닉을 원한다면 인터페이스 제어, 속성(Property) 관리, 클래스 설계 등으로 은닉의 효과를 최대화한다.

profile
꿈꾸는 것도 개발처럼 깊게

0개의 댓글