변수나 함수에 붙는 언더바(_)는 뭘까?

요상한 언더바

다른 사람들이 작성한 코드나 라이브러리를 보면, 변수나 함수의 이름 앞뒤에 _가 붙어 있는 걸 간혹가다 볼 수 있다. 대부분의 언어에서 _$와 함께 변수/함수명에 허용되는 유이한 특수문자다. 따라서 일반적으로 코딩 컨벤션에서 허용하는 경우가 아닌 이상(EX. 스네이크 기법) 해당 특수문자들이 변수명이나 함수명에 사용되는 경우는 흔하지 않다. 즉, _를 쓴다는 것은 해당 변수/함수명이 가지는 특수한 성질을 알려주고자 할 때 쓰이는 경우가 많다고 볼 수 있다. _의 위치나 개수, 그리고 언어에 따라 의미가 다양하나, 여기서는 대부분의 언어에서 통상적으로 많이 쓰는 한 개 짜리 _ 언더바에 대해서 만 다루도록 하겠다.


앞에 붙는 언더바

_var, _function()과 같이 변수/함수명 앞에 붙는 _JavaScriptPython 코드에서 주로 볼 수 있다. 이런 언어들의 특징은 Java와 같은 언어와 달리, 언어 레벨에서 접근 제한자 키워드를 제공하지 않는 언어들이다. 특정 범위 내에서만 사용하고 싶은 변수나 함수가 있을 때, 해당 변수/함수 이름 앞에 _를 하나 붙인다. Java로 따지자면 priavte 접근 제한자를 사용한 것과 동일한 의미이다.

class Example:
    def __init__(self):
        # _data 지역 변수는 외부에서 직접 접근을 지양할 것을 알린다
        self _data = []
    
    # 대신 아래의 함수들을 이용해 _data에 간접적으로 접근하자
    def get_data(self):
        return self._data
        
    def add_data(self, new_data):
        self._data.append(new_data)

이렇게 이름 앞에 _가 붙어 있다면, 다른 개발자들은 '아, 이 변수나 함수는 외부에서 호출할 수 없구나!'라는 것을 명시적으로 알 수 있다. 물론, 언어 레벨에서 직접 접근을 제한하는 것은 아니기 때문에, 코드를 작성하면 이름과 관련 없이 실제로는 동작한다. 하지만, 이는 해당 코드를 작성한 개발자가 의도한 바가 아니기 때문에 외부에서 직접 호출해서 사용하는 것은 지양해야 한다. 최신 IDE는 앞에 _가 붙는 변수나 함수를 자동 완성에서 제외 시키는 식으로 편의성을 제공하는 경우도 있다.


뒤에 붙는 언더바

반대로, var_, function_()과 같이 변수/함수명 뒤에 붙는 _는 마이그레이션의 흔적, 혹은 라이브러리에서 이미 사용 중인 이름과 충돌을 회피하기 위한 경우다. 마이그레이션은 타 언어로의 이주 혹은 버전 업그레이드를 의미한다. 이 과정에서 원래는 허용되었던 이름이 변경 된 언어에서 사용되는 키워드와 충돌하는 경우가 간혹 있다. 물론 가장 좋은 것은 다른 이름으로 바꾸는 것이지만, 그것이 어렵다고 판단되는 경우에는 이름 뒤에 _를 붙여 충돌을 회피할 수 있다.

// Java 9 이하
String var = "This is variable"

// Java 10 이상 부터는 var 라는 지역 타입 추론 변수 키워드가 생겼다!
String var_ = "This is variable"

해당 언어에서 사용 중인 라이브러리의 이름과 충돌을 피하기 위해서도 종종 사용된다. 예를 들어 라이브러리 명이 짧고, 또 너무 대중적인 이름을 쓰는 경우 변수명과 충돌하는 경우가 자주 있다. 예를 들어, Python에서 socket이라는 변수명을 사용하고 싶다고 가정하자. 그런데,  똑같은 이름을 가진 socket이라는 라이브러리를 사용 중일 경우 충돌이 발생할 수 있다. 이 때, 변수명의 이름을 socket_으로 명명해 충돌을 회피할 수 있다.

socket_ = socket.socket(AF_INET, SOCK_STREAM)
socket_.connect(("127.0.0.1", 8080))

변수명이 언더바...?

간혹가다, 그냥 변수명이 _인 경우도 있는데, 보통 for문이나 익명 함수에서 자주 볼 수 있다. 이런 경우는 변수명을 굳이 지정할 필요가 없거나, 불필요한 값임을 명시하기 위해 사용한다. 몇몇 언어에서는 익명 함수 선언 시, 매개변수가 없는 함수의 경우 ()보다 _를 쓰는 경우도 있다. 이유는 타이핑 횟수가 1회 줄어들기 때문이다.

# 변수명을 지정할 필요가 없는 경우
for _ in range(5):
    # 변수의 scope가 명확하고, 하나뿐이므로 그냥 _를 써도 무방
    print(_)
    
# 불필요한 값임을 명시
a, _, b = (1, 2, 3)
print(a + b)
// 익명 함수에서 매개변수가 없는 경우, 그냥 _ 하나만 적어도 상관없다
function arrowFunction = _ => {
    // ...do something
}

정리하며

Java 언어만 사용할 때는 잘 몰랐지만, 다양한 언어를 익히면서 의문을 가졌던 _ 사용의 이유를 알아보는 계기가 되었다. 여러모로 IDE의 지원이 조악하던 시절, 개발자들이 조금이라도 편하게 개발하기 위해 만들어낸 약속이라는 것에 큰 흥미를 가지며 조사를 하였으며, 이 지식이 다른 사람들에게도 도움이 되기를 바라며 글을 마친다.

+ P.S. 참고로 해외에서는 언더바(Under-bar)라는 표현보다는 언더스코어(Underscore)라는 표현을 주로 사용한다고 한다.


참고한 문헌 및 글

  1. 파이썬에서 언더바/언더스코어(_) 의 의미와 역할 :: 아인스트라세의 SW 블로그 (tistory.com)
  2. [JavaScript]언더바 변수 (tistory.com)
  3. 파이썬(python) - _(언더바, 언더스코어) (tistory.com)