Python 에서 언더스코어는 5가지 사용법으로 구분된다
Single Underscore:
- In Interpreter
- After a name
- Before a name
Double Underscore:
- __leading_double_underscore
- __before_after__
다음은 위와 같이, 파이썬 프롬프트에서 _ 기호가 변수로 사용되는 경우이다
추출된 값을 굳이 사용할 필요가 없는 경우에 그 값을 무시하는 의도
# 아래의 문장은 0 ~ 4까지 화면에 표시한다
for x in range(5):
print(x)
# 아래의 문장도 위와 동일한 결과를 표시한다
for _ in range(5):
print(_)
# 아래의 문장은 0 ~4까지의 숫자가 필요한 것이 아니라 5번 루프를 실행할 목적으로 사용된다
for _ in range(5):
print("Hello")
def test():
return (3,5,2,1) # Tuple을 리턴하는 함수
print( test() )
a, b, _, _ = test() # 리턴된 튜플의 두번째 값 까지만 필요한 경우
print(f"a:{a}, b:{b}")
이름 뒤에 _ 가 붙는 경우 (예약어는 변수명으로 사용할 수 없으므로 이름 뒤에 _를 붙인 경우)
class Product:
def __init__(self):
self.name = "Galaxy 10"
def printClsName(class_): # class라는 변수명을 사용하고자 하지만 Python 예약어라서 안됨
print(class_)
p1 = Product()
printClsName(p1.__class__) # <class '__main__.Product'>
함수이름 왼쪽에 _가 붙는 경우
보안성이 약한 private 의미로 사용하는 경우, 함수이름 왼쪽에 _붙이면 다른 파일에서 from file_name import * 방법을 사용하여 가져올 때 해당 함수는 누락되어 사용할 수가 없게 된다
util.py
def func1():
print("public function")
def _func2():
print("private function")
위의 util.py 파일을 다른 파일에서 사용하는 경우 ( _func2() 함수는 정의되지 않은 함수라는 오류 발생 )
from util import *
func1()
_func2()
위의 오류는 다음과 같은 방법으로 해결된다
import util
util.func1()
util._func2()
더블 언더스코어를 변수 왼쪽에 붙인 경우(Mangling)
Product.py ( __price 변수는 선언된 클래스에서 그 이름으로 사용가능하지만 외부에서는 안됨)
class Product:
def __init__(self):
self.name = "Galaxy 10"
self.__price = 300
def print_info(self):
print(f"name:{self.name}")
print(f"price:{self.__price}")
위의 클래스를 외부에서 사용하면서 __price 변수에 직접 접근하는 경우에 오류가 발생한다. 더블언더스코어가 2개 붙은 변수는 인터프리터에서 변수 이름을 고칠 때 _클래스명__변수명 형식으로 변경하기 때문이다. 이런 작업을 Mangling(맹글링)이라고 한다
import Product as p
p1 = p.Product()
#print( p1.__price) # 오류
print( p1._Product__price) # 정상
p1.print_info() # 정상
__이름__ 형식의 함수/변수
인터프리터에 내장된 특수한 함수/변수를 나타낸다
__init__() 생성자 함수가 여기에 속한다
또한 클래스 안에 정의할 수 있는 가감승제 메소드( __add__(), __sub__(), __mul__(), __divmod__() 등)도 있다. 이들 함수가 클래스에 정의되어 있으면 obj.__add__(2,3) 형식으로 호출할 수 도 있고 수학의 덧셈식( obj1 + obj2)형식으로도 호출할 수 있기 때문에 연산자 오버로드용으로 사용할 수 있다
__add__() 함수를 정의하여 벡터 덧셈을 직관적으로 표현한 경우(연산자 오버로드)
class vector:
def __init__(self, x,y,z):
self.x = x
self.y = y
self.z = z
def __add__(self, other):
x_ = self.x + other.x
y_ = self.y + other.y
z_ = self.z + other.z
return vector(x_,y_,z_)
def print_info(self):
print(f"x:{self.x}, y:{self.y}, z:{self.z}")
v1 = vector(1,2,3)
v2 = vector(4,5,6)
v3 = v1 + v2
v3.print_info() # x:5, y:7, z:9
Weak Private, Strong Private
Setter, Getter에서는 싱글 언더스코어, 더블 언더스코어 모두 사용할 수 있고 심지어 3개 이상도 가능하다
변수 왼쪽에 언더스코어를 2개이상 사용하면 Mangling 이 적용된다