해쟈스토리

파이썬에서의 밑줄 본문

파이썬/클린코드

파이썬에서의 밑줄

해쟈 2024. 6. 14. 12:24
728x90
반응형

다른 언어에서는 public, private, protected와 같은 접근 제어자를 제공한다. 그러나 파이썬은 이런 형태를 제공하지 않는다. Python의 모든 속성과 함수들은 public이다. 즉, 호출자가 객체의 속성을 호출하지 못하도록 할 방법이 없다.

엄격한 강제사항은 아니지만 파이썬에는 변수명 지정과 관련하여 몇 가지 네이밍 컨벤션이 있다. 

그 중에 하나로 밑줄로 시작하는 속성은 private 속성을 의미한다. 그러나 이것이 외부로부터의 호출을 금지시켜 주는 것은 아니다.

 

class Connector:
	def __init__(self, source):
    	self.source = source
        self._timeout = 60
               

>>> conn = Connector("postgresql://localhost")
>>> conn.source
'postgresql://localhost'
>>> conn._timeout
60

위와 같이 _timeout으로 private 속성으로 만들었지만 실제로는 인스턴스 객체를 통해 _timeout 변수에 접근이 가능하다.

다만, 이렇게 네이밍 컨벤션을 붙이므로써 명시했으므로 규칙만 잘 지켜졌다면 timeout 속성은 내부에서만 사용하고 바깥에서 호출되지 않을 것이므로 외부 인터페이스를 고려하지 않고 언제든 안전하게 리펙토링할 수 있다. timeout 속성을 변경할때 파급효과를 걱정하지 않아도 되므로 보다 쉽고 안전하게 유지보수를 할 수 있다.

 

객체의 인터페이스로 공개하는 용도가 아니라면 모든 멤버는 접두사로 하나의 밑줄을 사용하는 것이 좋다.

 

이중 밑줄을 하게 되면 private으로 사용할 수 있다는 오해를 많이 한다. 하지만 이것은 사실이 아니다.

class Connector:
	def __init__(self, source):
    	self.source = source
        self.__timeout = 60
        
    def connect(self):
    	print(f"connecting with {self.__timeout}s")
               

>>> conn = Connector("postgresql://localhost")
>>> conn.connect()
connecting with 60s
>>> conn.__timeout
Traceback (most recent all last):
	File "<stdin>", line 1, in <module>
AttributeError: 'Connector' object has no attribute '__timeout'

위 예제를 보소 어? timeout 변수에 접근못하네 private으로 된거 아냐? 하고 오해를 많이 하는데, 파이썬은 밑줄 두개를 사용하면 다른 이름을 만든다. 이것을 name mangling(이름 맹글링)이라고 하는데, 변수의 이름을 "_<class_name>__<attribut-name>' 형태로 변경하는 것이다.

var(conn)
{'source': 'postgresql://localhost', '_Connector__timeout': 60}
>>> conn._Connector__timeout
60
>>> conn._Connector__timeout = 30
>>> conn.connect()
connecting with 30s

 

위와 같이 "_<class_name>__<attribut-name>' 형태로 접근가능하며 값도 변경할 수 있다.

그러면 파이썬에서 이중 밑줄을 사용은 언제 하는 것일까? 이것ㅇ의 용도는 여러번 확장되는 클래스의 메서드를 이름 충돌없이 오버라이드하기 위해 만들어졌다.

그래서 이와 같은 사유가 아니라면 이중 밑줄을 한 속성과 메서드를 만들지 않도록 해야한다.

 

참조 : 유지보수가 쉬운 파이썬 코드를 만드는 비결 파이썬 클린코드 2nd Edition - 마리아노 아나야

728x90
반응형

'파이썬 > 클린코드' 카테고리의 다른 글

결합도  (0) 2024.08.19
방어적 프로그래밍  (0) 2024.08.19
dataclasses 모듈  (1) 2024.06.17
Property  (0) 2024.06.14
매직메소드(__enter__와 __exit__, 그리고 contextlib)  (0) 2024.06.13