파이썬에서의 맹글링

주어진 예를 통해 이 개념을 이해해 봅시다.

  class Parent:

    def __init__(self):
      self.name = "ayush"
      self.__age = 21

    def get_name(self):
      return self.name

    def __get_age(self):
      return self.__age


  obj = Parent()

  print(obj.get_name())
  print(obj.__get_age())
  print(obj.__age)


위의 코드는 구문적으로는 올바른 것 같지만 실행 시 다음 오류가 발생합니다.

AttributeError: 'Parent' object has no attribute '__get_age'


그렇다면 위의 코드에서 AttributeError가 발생하는 이유는 무엇입니까?
답은 간단합니다. 이것은 파이썬의 이름 맹글링 때문입니다.

이 문제의 답은 문제 자체에 있습니다. 속성 참조 또는 할당이 실패하면 AttributeError가 발생하기 때문입니다.

부모 클래스 범위의 이름 목록을 분석하여 문제를 조금 더 살펴보겠습니다. 이를 위해 dir()을 사용할 수 있습니다.

print(dir(obj))

['_Parent__age', '_Parent__get_age', '__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__', 'get_name', 'name']



여기에 두 개의 속성('Parentage', '_Parent_get_age')이 있으며 그 이름은 암시적으로 클래스 이름과 병합됩니다. 즉, 속성 이름이 클래스 이름과 엉망이라고 말할 수 있습니다.

부모 클래스 범위에는 __age 및 __get_age 식별자에 대한 참조가 없으므로 AttributeError가 발생합니다.

맹글링이란?



Name Mangling은 선행 밑줄이 2개 있는 식별자(예: __age)를 텍스트로 classname_age로 대체하는 메커니즘에 불과합니다.

지금까지 우리는 이 메커니즘을 식별자의 명명을 제한하는 문제로 간주했습니다. 그러나 실제 시나리오에서는 어떤 상황에서는 도움이 됩니다.

이름 맹글링이 사용되는 몇 가지 경우에 대해 논의해 봅시다.
  • 때로는 맹글링이 파이썬에서 개인 멤버를 구현하는 방법으로 간주될 수 있습니다.
    위의 예에서 우리는 클래스 외부에서 맹글링된 변수에 액세스하려고 시도하지만 클래스 내부에서 변수가 동일한 이름으로 참조될 때 AttributeError가 발생하는 것을 확인했습니다.
    하지만 함정이 있습니다. 훼손된 이름으로 속성을 참조하여 이러한 개인 멤버에 액세스할 수 있습니다.

  •   print(obj._Parent__age)
    


    그래서, 파이썬에서 완벽한 사생활은 없습니다... 😩😩😩

  • 재정의: 재정의는 하위 클래스가 부모 클래스의 메서드를 재정의할 수 있도록 하는 OOP의 기능입니다. 하위 클래스의 메서드는 슈퍼 클래스 메서드와 동일한 이름 및 시그니처를 가집니다.

  •     class Parent:
    
          def __init__(self):
            self.name = "ayush"
            self.age = 21
    
          def get_name(self):
            return self.name
    
          def get_age(self):
            return f"Parent class -  {self.age}"
    
        __get_age = get_age # private copy of original get_age method
    
      class Child(Parent):
    
          def __init__(self):
            self.name = "abc"
            self.age = 23
    
          def get_name(self):
            return self.name
    
          def get_age(self):
            return f"Child class -  {self.age}"
    
      child = Child()
    
      print(child.get_age()) # Child class - 23
      print(child._Parent__get_age())  # Parent class - 23
    


    위의 예에서 알 수 있듯이 이름 맹글링은 클래스 내 메서드 호출을 중단하지 않고 하위 클래스가 메서드를 재정의하도록 하는 데 유용합니다.

    결론



    위 논의의 결론은 변수( __var 와 같은) 이름을 클래스 맹글링 이름으로 암시적으로 변환하는 것이 파이썬의 내장 기능이라는 것입니다. 맹글링된 변수는 위에서 설명한 것처럼 다양한 상황에서 사용할 수 있습니다.

    좋은 웹페이지 즐겨찾기