본문 바로가기

Python

Python: name mangling 된 메소드 오버라이딩 # __method #

728x90
반응형

Python 클래스에서

 

언더바 두개가 붙는 메소드는 private하게 취급이 된다.

 

class Base:
    ...
    def __test_method(self)

 

와 같이 선언된 __test_method의 경우, 메소드 명이 변경되는 name mangling이 일어난다.

name mangling이 되면 __test_method로 선언한 명칭이 변경이되기 때문에,

Base를 상속받은 다른 클래스에서 __test_method라고 메소드 선언을 해도 오버라이딩이 일어나지 않는다.

 

이와 같이, 다른 곳에서 쉽게 오버라이드 되지 않도록 일종의 예방 차원에서 __ 형태를 쓸 수 있다.

 

그렇지만 외부라이브러리 등을 사용하는 경우에 name mangling된 메소드를 오버라이드 할 상황이 생긴다.

(예를 들어 특정 warning print를 제거하고 싶다던가..)

이때 name mangling된 메소드를 오버라이딩하는 방식은

원래 메소드 명에 언더바 하나가 붙은 클래스 명을 붙이는 것이다.

 

class Base:
    def __init__(self):
        self.__private_method()

    def __private_method(self):
        print("Base private method")

class Derived(Base):
    def __private_method(self):  # This does NOT override the Base __private_method
        print("Derived private method")

    def _Base__private_method(self):  # Correct way to override the private method
        print("Correctly overridden private method")

# Testing the classes
base = Base()        # Outputs: Base private method
derived = Derived()  # Outputs: Correctly overridden private method

 

 

C와는 다르게 C++은 함수오버라이딩 기능을 제공하고,

오버라이딩 시에 C++에서도 name mangling을 이용한다.

또한 C언어에서도 static으로 선언된 변수에서는 name mangling이 일어난다.

이와 같은 name mangling이 일어나는 extern "C"와 static 변수 선언과 관련된 스크랩 링크를 연결해두었다.

완전 같은 맥락은 아니어도 name mangling에 대한 전반적인 이해를 하는데 도움이 되는 듯 싶다.

 

https://taltal-dev-note.tistory.com/324

 

 

Chat GPT 답변 내역도 남긴다.

 

 
How to override __ prefixed method in python?
 
ChatGPT

In Python, methods that begin with double underscores (__) are often considered "private" methods, although Python itself does not enforce strict access restrictions as some other languages do. This naming convention triggers name mangling, where the method name is prefixed with _ClassName to prevent it from being easily accessible from outside the class.

If you want to override a method that has been name-mangled in a subclass, you must use its mangled name. Here's how it works:

  1. Understanding Name Mangling: When you define a method like __method in a class named Base, Python internally changes its name to _Base__method. This is meant to prevent the method from being overridden accidentally in subclasses.
  2. Overriding the Method: To override this method in a subclass, you must use the mangled name based on the base class where the method was defined.

Here is an example to demonstrate how you can override a private method in Python:

class Base:
    def __init__(self):
        self.__private_method()

    def __private_method(self):
        print("Base private method")

class Derived(Base):
    def __private_method(self):  # This does NOT override the Base __private_method
        print("Derived private method")

    def _Base__private_method(self):  # Correct way to override the private method
        print("Correctly overridden private method")

# Testing the classes
base = Base()        # Outputs: Base private method
derived = Derived()  # Outputs: Correctly overridden private method

 

In the Derived class:

  • __private_method is treated as a new method specific to Derived and does not affect the method in Base.
  • _Base__private_method is the correctly mangled name to override the private method defined in Base.

This example highlights the correct approach to override a method that is considered private through name mangling in Python. It's a bit of a workaround and goes against the spirit of using private methods (which are meant to discourage or prevent overriding), so it should be used judiciously and considerately.

728x90
반응형