Home [Python] Underscore의 사용
Post
Cancel

[Python] Underscore의 사용

Python에서는 Underscore( _ )를 다양한 상황에서 사용합니다. 오늘은 Python에서 사용하는 Underscore에 대해서 알아보려고 합니다.


1. Python에서 언더스코어를 사용하는 경우

  • 변수에 값을 할당하지 않고 무시할 때
  • 숫자 자릿수를 구분 할 때
  • 모듈(.py)내에서만 변수 / 함수를 사용할 때
  • 예약어와 같은 이미 지정된 변수 / 함수의 이름과의 충돌을 피하기 위해
  • 맨글링(Mangling)
  • 매직 메소드(Magic Method)

위의 경우들을 지금부터 하나씩 알아보겠습니다.

2. 변수에 값을 할당하지 않고 무시할 때

1
2
3
4
5
6
list_ex = [1, 2, 3, 4, 5]
one, two, _, four, five = list_ex
print(one, two, _, four, five)
    >>  1 2 3 4 5
print(f'{_} == three')
    >>  3 == three

위와 같이 리스트를 언패킹 할 때 언더스코어가 사용됩니다. 그러나 언더스코어를 사용했다고 해서 값 자체가 할당이 되지 않는 것은 아닙니다.

언더스코어가 값을 할당 받았기 때문에 변수로 사용이 가능할 것 같은데 왜 언더스코어를 사용해서 무시를 할지 한 번 생각해 봐도 좋을 것 같습니다.

➡️ 저의 생각은 다음과 같습니다. 누군가가 프로그래밍을 할 때는 혼자만 사용하기 위한 코드를 작성하지 않습니다. 해당 프로그램을 공유 할 수도 있고 누군가와 협업을 진행 할 수도 있습니다. 그렇다면 네이밍이라는 것은 굉장히 중요해지며 해당 코드를 이해하는데 불필요한 것들은 최대한 줄이는 것이 굉장히 중요합니다. 그렇기 때문에 이후에 사용하지 않는다는 의미에서 언더스코어를 사용하지 않았을까 생각합니다.😁

3. 숫자 자릿수를 구분 할 때

😂 많이 사용은 안하는 것 같습니다.

숫자를 세는 경우 천 단위로 끊어서 보통 콤마(,)를 사용합니다. 그러나 python에서 숫자를 세기 위해 콤마를 찍을 순 없습니다. 이 때 언더스코어를 사용하시면 콤마의 역할을 대체할 수 있습니다.

1
2
3
4
5
6
7
money = 10000000000
print(money)
    >>  10000000000

money = 10_000_000_000
print(money)
    >>  10000000000

4. 모듈(.py)내에서만 변수 / 함수를 사용할 때

모듈 Test_module.py를 만들어 보겠습니다.

1
2
3
4
5
6
7
# Test_module.py
def default_function():
    print("기본적인 함수")


def _underscore_function():
    print("underscore를 앞에 하나 붙인 함수")
1
2
3
4
5
6
7
# Test.py
from Test_module import *

default_function()
    >>  기본적인 함수
_underscore_function()
    >>  NameError: name '_underscore_function' is not defined

모듈 Test_module.py를 만들고 Test.py에서 test를 해본 결과 언더스코어를 함수 앞에 하나 붙인 _underscore_function의 경우 사용할 수 없는 것을 알 수 있습니다.

방금한 test에서는 Test_module로부터 모든 method들을 불러왔습니다. 이번에는 직접 하나씩 불러오도록 해보겠습니다.

1
2
3
4
5
6
from Test_module import default_function, _underscore_function

default_function()
    >>  기본적인 함수
_underscore_function()
    >>  underscore를 앞에 하나 붙인 함수

위의 코드에서도 볼 수있듯이 언더스코어를 앞에 붙인 method를 직접 import 시켰더니 사용이 가능한 것을 볼 수 있습니다.

해당 방법은 method의 사용을 조심히 할 필요가 있을 때 사용하면 좋을 것 같습니다.

5. 예약어와 같은 이미 지정된 변수 / 함수의 이름과의 충돌을 피하기 위해

👍알아두면 유용해요~~

앞에서도 언급했듯이 프로그래밍을 할 때 네이밍은 무엇보다도 중요할 수 있습니다. 그러나 Python에서는 예약어(if, for)과 같은 이미 python이 설치될 때 정해진 이름들이 있습니다. 또한 프로그래밍을 하다 보면 비슷한 역할아지만 변수명을 다르게 사용해야 할 때 네이밍 하기가 굉장히 힘들 수 있습니다. 이때 이름 뒤에 언더스코어를 하나 붙이면 사용이 가능합니다.

1
2
3
4
5
6
7
my_name = 'Gil Dong Hong'
print(my_name)
    >>  Gil Dong Hong

my_name_ = '홍길동'
print(my_name_)
    >>  홍길동
1
2
3
list_ = [1, 2, 3, 4, 5]
print(list_)
    >>  [1, 2, 3, 4, 5]

🖥️ 아래 나오는 두 가지 사용법은 특히 github에서 다른 사람의 코드를 볼 때 또는 프로젝트 수준의 큰 코딩을 할 때 굉장히 중요한 것 같습니다.

6. 네임 맨글링(Name Mangling)

6.1 Private 속성 추가하기

1
2
3
4
5
6
7
8
9
10
11
12
13
class Resume():
    def __init__(self):
        self.name = "홍길동"
        self.age = "20"
        self.hobby = "축구"

person = Resume()
print(person.name)
    >>  홍길동
print(person.age)
    >>  20
print(person.hobby)
    >>  축구

Private 속성을 추가하지 않았기 때문에 class 밖에서도 접근이 가능합니다. 그러나 이런 경우 class의 변수 값이 본인의 의도와 상관없이 바뀔 수 있으므로 이를 방지하기 위해서는 private 속성을 추가해야 합니다. Python에서는 언더스코어를 변수명 앞에 두개 붙여줍니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
class Resume():
    def __init__(self):
        self.name = "홍길동"
        self.age = "20"
        self.__hobby = "축구"

person = Resume()
print(person.name)
    >>  홍길동
print(person.age)
    >>  20
print(person.hobby)
    >>  AttributeError: 'Resume' object has no attribute '__hobby'

그러면 AttributeError가 발생하면서 접근이 불가능하게 됩니다.

그런데 접근을 해야 할 경우가 있을 수 있습니다. 이럴땐 property decorator를 사용해 private 속성을 가진 변수도 접근이 가능하게 할 수 있습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Resume():
    def __init__(self):
        self.name = "홍길동"
        self.age = "20"
        self.__hobby = "축구"

    @property
    def hobby(self):
        return self.__hobby

person = Resume()
print(person.name)
    >>  홍길동
print(person.age)
    >>  20
print(person.hobby)
    >>  축구

위의 방법 말고도 아래와 같이 클래스 이름을 통해 접근하는 방법도 있습니다.

ObjectName._ClassName__PrivateVariableName

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Resume():
    def __init__(self):
        self.name = "홍길동"
        self.age = "20"
        self.__hobby = "축구"

    @property
    def hobby(self):
        return self.__hobby

person = Resume()
print(person.__dict__)
    >>  {'name': '홍길동', 'age': '20', '_Resume__hobby': '축구'}
print(person._Resume__hobby)
    >>  축구

6.2 Overriding

Overriding : 상위 클래스의 method와 이름이 같은 함수를 하위 클래스에 재정의 하는 것을 말합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Resume():
    def __init__(self):
        self.name = "홍길동"
        self.age = "20"
        self.hobby = "축구"

class English_resume(Resume):
    def __init__(self):
        super().__init__()
        self.name = "Gil-Dong Hong"
        self.age = "20"
        self.hobby = "Soccer"

english_person = English_resume()
print(english_person.name)
    >>  Gil-Dong Hong
print(english_person.age)
    >>  20
print(english_person.hobby)
    >>  Soccer

위 코드는 정상적인 오버라이딩이 수행되는 코드이다. 아래 코드에서 언더스코어를 사용하면 어떻게 될지 한 번 살펴보겠습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Resume():
    def __init__(self):
        self.name = "홍길동"
        self.age = "20"
        self.__hobby = "축구"

class English_resume(Resume):
    def __init__(self):
        super().__init__()
        self.name = "Gil-Dong Hong"
        self.age = "20"
        self.__hobby = "Soccer"

english_person = English_resume()
print(english_person.name)
    >>  Gil-Dong Hong
print(english_person.age)
    >>  20
print(english_person.__hobby)
    >>  AttributeError: 'English_resume' object has no attribute '__hobby'

7. 매직 메소드(Magic Method)

매직 메소드 : 메소드 앞 뒤에 언더스코어를 두 개씩 붙인것을 매직 메소드라고 하며 여러가지 Built-in 함수들이 처리할 연산을 정의한 것을 말합니다.

대표적인 매직 메소드는 __init__, __add__, ___str__등이 있습니다. 그 중에서 __add__를 사용하는 방법은 다음과 같습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Resume():
    def __init__(self):
        self.name = "홍길동"
        self.age = "20"
        self.hobby = "축구"

    def __add__(self, other):
        return int(self.age) + int(other.age)

person1 = Resume()
person2 = Resume()

print(person1 + person2)
    >>  40

Python에서 정의할 수 있는 매직 메소드는 필요에 따라 공식문서나 여러 자료들을 찾아가며 프로그래밍 하실 수 있을 것 같습니다.


※ Reference

This post is licensed under CC BY 4.0 by the author.

[Python] Tree - 탐색 하는 방법

[Evaluation] BLEU