본문 바로가기
IT/Python

Python 에서의 _(underbar/언더바) 의 역할

by 성준하이 2024. 5. 15.
반응형

파이선에서 _ (이하 언더바) 의 역할은 다양하게 사용 된다.

 

먼저 언더바의 역할을 아래 리스트로 나열하면

  • 인터프리터에서의 마지막 값
  • 무시하는 값
  • 숫자 리터럴의 자릿수를 구분하는 역할
  • 네이밍

이다.

 

인터프리터에서의 마지막 값

​인터프리터 내에서의 마지막 값을 의미한다.

>>> 1+1
2
>>> _ + 1
3

2번째 명령줄의 언더바가 바로 윗줄의 2를 의미한다.

 

무시하는 값
n_tuple = (1, 2, 3, 4, 5)
a, b, c, _, e = n_tuple  # 4는 무시하고 1,2,3,5만 언패킹
print(a, b, c, e)

출력 결과
## 1 2 3 5

 

숫자 리터럴의 자릿수를 구분하는 역할
number = 100_000_000
number_2 = 0x_5f_5e_100
print(number, number_2)

출력 결과
##100000000 100000000

말그대로 자리수 구분의 역할이다.

 

네이밍

네이밍은 좀더 자세하게 몇가지로 나뉜다.

  • 맨앞에 언더바 하나 붙는경우(_test)

 이 경우는 모듈 내에서만 private 형식으로 해당 변수/함수를 사용하겠다는 의미이다.

특히 협업 시 '이 변수/함수는 이 모듈 내부에서만 사용한다' 라는 의미로 생각하면 된다.

단, 완전한 의미의 private는 아니기 때문에 여전히 해당 변수/함수는 접근하거나 사용할 수 있다. 파이썬은 private와 public의 확실한 구분이 없다.
하지만 외부 모듈에서 해당 모듈을 from module_name import * 식으로 전체 임포트 할 때 앞에 언더바가 붙은 변수/함수는 임포트를 하지 않는다.

test_module.py

def _hi():
    print('hi')

def hello():
    print('hello')


test_module이라는 모듈을 만들었고 함수를 2개 선언했는데 하나는 앞에 언더바를 붙이고 하나는 붙이지 않았다.

from test_module import *

hello()
_hi() # 에러 발생


그리고 다른 모듈에서 해당 모듈을 from과 *로 임포트했다.

이 상태로 아까의 내부 함수를 2개 실행하려고 하면, 앞에 언더바가 붙은 함수를 찾을 수 없다면서 에러를 발생시킨다.

하지만 위에 말한것처럼 이는 완전한 private는 아니기 때문에 직접 가져오거나 호출하면 사용이 가능하다.

from test_module import hello, _hi

hello()
_hi() # 에러 없이 정상 실행

 

  • 뒤에 언더바 하나 붙는경우(test_)

이 경우는 파이썬 키워드와 변수/함수명의 충돌을 피하기 위해 사용하는 경우이다.

list_ = [1, 2, 3, 4, 5]

def print_(args):
    print('hi')
    print(args)

print_(list_)

출력 결과
hi
[1, 2, 3, 4, 5]

 

  • 앞에 언더바 두개 붙는경우(__test)

이 경우는 네이밍 룰이라기 보단 문법적인 요소로 생각하면 된다.

바로 네임 맹글링(name mangling)을 위한 경우다. (맹글링은 '짓이기다'라는 뜻으로 쉽게 말하자면 파이썬이 해당 변수/함수의 이름을 짓이겨서 바꿔버리는 것을 의미)


맹글링을 당한 변수/함수는 본연의 이름으로 접근할 수 없게 된다.

class TestClass():
    def __init__(self):
        self.name = "thenicesj"
        self.gender = "male"
        self.__age = 30

man = TestClass()

print(man.name)
print(man.gender)
print(man.__age) # AttributeError 발생

에러가 발생하는 이유는 아래 출력에서 볼수 있다.

print(dir(man))
['_TestClass__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__', 'gender', 'name']

print(man._TestClass__age) # 30 출력

이라고 작성을 해야 원하는 출력이 나온다.

 

  • 앞에,뒤에 언더바 두개씩 붙는경우(__test__)

파이선만의 특별히 정의한 변수나 함수에 사용되는 룰이다.

대부분이 오버라이딩 전용으로 사용이 될것이고 이런 네이밍 룰이 적용된 함수는 매직메서드 / 던더메서드라고 부른다.

대표적으로는 __init__ 함수가 있다.

class TestClass():
    def __init__(self):
        print("Hello World")

test = TestClass()
반응형

댓글