Skip to content

2.15. 내용정리: 15일차

흔한 찐따 edited this page Mar 23, 2022 · 1 revision

파이썬에서의 언더바 기호( _ )의 의미

파이썬에서의 언더바 혹은 언더 스코어(under-score) 기호 _ 는 특별한 의미를 가지며, 다양한 쓰임새가 있다.

  1. 인터프리터의 마지막 값을 나타내는 경우
  2. 값을 무시하고 싶을 경우
  3. 변수나 함수명에 특별한 의미를 부여하는 경우
  4. 숫자의 자릿수 구분을 위한 구분자로써의 용도

1. 인터프리터의 마지막 값을 나타내는 경우

  • 파이썬 IDLE을 처음 실행시키면 나오는 창이나 명령 프롬프트에서 파이썬을 실행하면 파이썬 인터프리터, 즉 대화형 셀이 나오는데, 이에 대한 마지막 값을 나타낸다.
  • 참고로, 파이썬 대화형 셀을 REPL이라고 한다.
    • REPL(read-eval-print loop) 또는 인터랙티브 톱레벨(interactive toplevel), 랭기지 셸(language shell) 은 단일 사용자의 입력(예: 단일 식)을 취하고 이를 평가(실행)하고 결과를 사용자에게 반환시키는 단순한 상호작용 컴퓨터 프로그래밍 환경이다.
    • REPL 환경으로 작성된 프로그램은 구간마다 실행된다.
    • 이 용어는 보통 클래식 리스프 머신 상호작용 환경과 유사한 프로그래밍 인터페이스를 의미하기도 한다.
    • 일반적인 예로는 프로그래밍 언어를 위한 명령 줄 셸 및 유사 환경을 들 수 있으며 기법은 스크립트 언어의 특징과 매우 닮아있다.
Microsoft Windows [Version 10.0.19044.1620]
(c) Microsoft Corporation. All rights reserved.

C:\Users\iamjjintta>python
Python 3.10.3 (tags/v3.10.3:a342a49, Mar 16 2022, 13:07:40) [MSC v.1929 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> 1
1
>>> _
1
>>>

2. 값을 무시하고 싶을 경우

  • PEP8에 의하면, 파이썬은 관례적으로 값을 무시하고 싶은 경우, 언더바 기호 _ 를 사용하도록 명시하고 있다.
  • 주로 언패킹을 하는 경우나 for 문을 사용하여 반복문을 실행할 때 변수를 사용하지 않을 경우에 언더바 기호 _ 를 사용한다.
a, b = 1, 2

# '1 2'가 출력된다.
print(a, b)

c, *_, d = 1, 2, 3, 4, 5

# '1 5'가 출력된다.
print(c, d)

# '[2, 3, 4]'가 출력된다.
print(_)

# '안녕하세요'가 총 4번 출력된다.
for _ in range(1, 5):
    print('안녕하세요')

3. 변수나 함수에 특별한 의미를 부여하는 경우

  1. 폴더 안에 __init__.py 파일을 생성하여 패키지로 만들때 사용한다.
  2. 변수나 함수명 앞에 언더바 기호 _ 가 한 번 붙으면 외부에서 한번에 import 하는 것을 방지하는 용도로 사용된다.
    • 예를 들어, from 패키지명 import * 로 패키지 안에 있는 모든 클래스나 함수들을 불러오는 것을 방지한다.
# test.py
_a = 10

def _f():
    print('Hello, Python!')
# test2.py
from test import *

# 아래의 코드를 실행시키면 다음과 같은 에러가 발생한다.
# NameError: name '_a' is not defined
print(_a)
_f()
  1. 메서드 앞에 언더바 기호 _ 가 두 번 붙으면 매직 메서드로 분류된다.
    • 위와 같이 함수나 메서드에 언더바 기호 _ 두 번을 붙여서 사용하는 기법을 맹글링(Mengling) 기법이라고 한다.

네임 맹글링 (Name Mangling)

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

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

class MyClass:
    def __init__(self):
        self.a = 10
        self.__b = 20


m = MyClass()
print(m.a)

# 아래의 코드를 실행하면 다음과 같은 에러가 발생한다.
# AttributeError: 'MyClass' object has no attribute '__b'
print(m.__b)

객체의 속성과 메서드를 확인할 수 있는 dir 함수를 통해 인스턴스 객체 m 의 속성과 메서드를 출력해보면 다음과 같다.

print(dir(m))

결과

['_MyClass__b', '__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__', 'a']
  • 위의 결과를 살펴보면 self.__b 로 선언한 변수가 _MyClass__b 로 변수명이 바뀐 것, 즉 네임 맹글링이 된 것을 확인할 수 있다.
  • 즉, m._MyClass__b 로 접근할 수 있으므로, 속성이 완전히 private 상태가 되는 것은 아니기에 일종의 편법이다.

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

class A:
    def __init__(self):
        self.a = 10
        self.__b = 20

class B(A):
    def __init__(self):
        super().__init__()
        self.a = 20
        self.__b = 30

b = B()
print(b.a)

# 이 역시 'AttributeError'가 발생한다.
print(b.__b)

4. 숫자의 자릿수 구분을 위한 구분자로써의 용도

숫자를 나타낼 때 구분자로써 10_000 와 같이 표현할 때 사용한다.

a = 10_000
b = 100_000

# '10000'이 출력된다.
print(a)

# '100000'이 출력된다.
print(b)

흔한 찐따

안녕하세요, 흔한 찐따 입니다.

Clone this wiki locally