파이썬

파이썬(python) - 네임 맹글링(name mangling)

티베트 모래여우 2020. 10. 30. 10:22
반응형

네임 맹글링(name mangling)이란?

네임 맹글링은 짓이기다(mangle)라는 어원에서 유추할 수 있듯이 파이썬이 변수/함수의 이름을 짓이겨서 다른 이름으로 바꿔버리는 것을 말합니다. 맹글링을 적용하고 싶은 변수/함수명 앞에 언더바(_)를 두 개 붙여서 적용할 수 있습니다.

맹글링에 대해서 잘 모르시는 분들은 이전 포스팅의 4-3문단을 참조해주세요.

 

파이썬(python) - _(언더바, 언더스코어)

파이썬에서 _(이하 '언더바'로 통일)의 역할 다른 언어와 다르게 파이썬에서 언더바는 Snake case로 네이밍을 할 때 외에도 다양한 사용처가 있습니다. 이는 아래와 같이 크게 4가지로 분류할 수 있

tibetsandfox.tistory.com

오늘 포스팅에서는 맹글링을 언제 사용하는지에 대해서 간단히 다뤄보겠습니다.

사실 사투리였던거임 아 ㅋㅋ


그래서 맹글링은 언제 사용하나요

파이썬에서 맹글링은 크게 2가지 상황에서 사용할 수 있습니다.

첫 번째는 클래스의 속성값을 외부에서 접근하기 힘들게 할 때(private화)

두 번째는 하위 클래스가 상위 클래스의 속성을 오버라이딩 하는 것을 막을때 입니다.

1. 클래스의 속성값을 외부에서 접근하기 힘들게 할 때

class TestClass:
    def __init__(self):
        self.name = "왕춘삼"
        self.age = 30
        self.hobby = "인형놀이"


man = TestClass()
print(man.name, man.age, man.hobby)

출력 결과
왕춘삼 47 인형놀이

위와 같은 코드가 있습니다.

보시다시피 아무런 변화를 주지 않은 평범한 코드이고 따라서 클래스의 속성값을 외부에서 손쉽게 접근할 수 있습니다.

만약 여기서 hobby라는 속성을 조금 숨기고 싶다면? 이럴 때 맹글링을 적용하면 됩니다.

(아무래도 30살에 인형놀이가 취미라고 하면 사회적인 시선이 고울 것 같지는 않기 때문에..)

class TestClass:
    def __init__(self):
        self.name = "왕춘삼"
        self.age = 47
        self.__hobby = "인형놀이"


man = TestClass()
print(man.name, man.age, man.__hobby) # AttributeError: 'TestClass' object has no attribute '__hobby'

맹글링 적용시 속성의 이름이 변경되기 때문에 외부에서는 더 이상 해당 속성 이름으로 접근할 수 없게 됩니다.

어느 정도 private의 성격을 띄게 된 것입니다.

man = TestClass()
print(dir(man))

['_TestClass__hobby', '__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__', 'age', 'name']

단, dir함수를 써 보면 알 수 있지만 이는 완벽한 private은 아닙니다.

첫 인덱스에 '_TestClass__hobby'라는 요소가 보이죠?

저 요소가 바로 맹글링이 적용된 hobby속성입니다.

즉 파이썬에서 맹글링을 적용한 속성은 _클래스명__속성명 의 형태로 이름이 바뀌는 것이고 이는 외부의 접근을 조금 어렵게 할 뿐 값을 완벽하게 보호해 주는 것은 아니라는 것입니다.

어딜 숨으려고

 

2. 하위 클래스가 상위 클래스의 속성을 오버라이딩 하는 것을 막을때

클래스가 확장되면서 크기가 커지면 발생할 수 있는 문제인 속성 이름간의 충돌을 막고자 할 때, 특히 오버라이딩을 막고자 할 때 맹글링을 적용시킬 수 있습니다.

class TestClass:
    def __init__(self):
        self.name = "왕춘삼"
        self.age = 30
        self.hobby = "인형놀이"


class TestClass2(TestClass):
    def __init__(self):
        super().__init__()
        self.name = "양팔두"
        self.age = 23
        self.hobby = "벽 보기"


man = TestClass2()
print(man.name, man.age, man.hobby)

출력 결과
양팔두 23 벽 보기

해당 코드는 아무런 조치를 취하지 않았습니다.

따라서 아무런 제약 없이 하위 클래스에서 상위 클래스의 속성들을 오버라이딩 할 수 있습니다.

class TestClass:
    def __init__(self):
        self.name = "왕춘삼"
        self.age = 30
        self.__hobby = "인형놀이"


class TestClass2(TestClass):
    def __init__(self):
        super().__init__()
        self.name = "양팔두"
        self.age = 23
        self.__hobby = "벽 보기"


man = TestClass2()
print(man.name, man.age, man.__hobby)
# AttributeError: 'TestClass2' object has no attribute '__hobby'

하지만 이와 같이 오버라이딩을 막고싶은 속성에 맹글링을 적용시키면 AttributeError가 발생합니다.

이름이 바뀌었기 때문에 __hobby 속성을 애초에 가지고 있지 않은 것으로 취급하는 것 입니다.

반응형