[카테고리:] 미분류

  • Python은 강력하고 유연한 언어지만, 백엔드 개발의 주요 언어로 선택하기 어려운 이유 중 하나는 접근 제어 방식이 Java 같은 언어에 비해 느슨하다는 점이다. Java에서는 private, protected, public 등의 키워드를 사용하여 멤버 변수와 메서드의 접근 수준을 엄격하게 제어할 수 있다. 하지만 Python에서는 이런 접근 제어자가 강제되지 않는다.

    1. Python의 접근 제어 방식

    Python에서는 모든 멤버 변수가 기본적으로 public이며, 일부 관례(convention)를 통해 보호 수준을 암시적으로 나타낸다.

    (1) Public Members

    일반적으로 선언된 변수와 메서드는 공개(public) 상태로, 어디서든 접근이 가능하다.

    class MyClass:
        def __init__(self):
            self.name = "Public Variable"  # 공개 변수
        
        def greet(self):
            return f"Hello, {self.name}!"
    

    이 변수는 클래스 내부뿐만 아니라 외부에서도 접근할 수 있다.

    obj = MyClass()
    print(obj.name)  # 가능
    obj.name = "Changed"  # 가능
    

    (2) Protected Members

    변수명 앞에 싱글 언더스코어 (_) 를 붙이면 보호(protected) 상태를 의미한다. 이는 내부적으로만 사용해야 한다는 신호일 뿐 강제적인 제한은 없다.

    class MyClass:
        def __init__(self):
            self._protected_var = "Protected Variable"
    

    외부에서 접근할 수 있지만, 이는 권장되지 않는 방식이다.

    obj = MyClass()
    print(obj._protected_var)  # 가능하지만 권장되지 않음
    

    (3) Private Members

    변수명 앞에 더블 언더스코어 (__) 를 붙이면 비공개(private) 상태가 된다. 이는 이름 맹글링(name mangling)을 적용하여 외부에서 직접 접근할 수 없도록 만든다.

    class MyClass:
        def __init__(self):
            self.__private_var = "Private Variable"
    

    외부에서 __private_var에 직접 접근하려고 하면 오류가 발생한다.

    obj = MyClass()
    print(obj.__private_var)  # AttributeError 발생
    

    하지만 Python에서는 이 역시 완벽한 차단이 아니라 이름 맹글링을 통해 _ClassName__변수명 형식으로 접근할 수 있다.

    print(obj._MyClass__private_var)  # 가능하지만 사용을 권장하지 않음
    

    2. Java와의 차이점

    Java에서는 접근 제어자가 강제된다. 예를 들어, private 키워드를 사용하면 해당 필드는 클래스 외부에서 접근할 수 없다.

    class MyClass {
        private String name = "Private Variable";
    
        public String getName() {
            return name;
        }
    }
    

    Python에서는 이러한 강제성이 없기 때문에 개발자가 명확한 코드 컨벤션을 따라야 한다.

    3. Python 접근 제어의 한계

    Python의 철학 중 하나는 “We are all consenting adults here” (우리는 모두 성인이다)이다. 즉, 접근 제한을 강제하기보다는 개발자가 협의된 규칙을 따르는 것이 중요하다는 입장이다. 하지만, 이러한 접근 방식은 대규모 프로젝트나 협업 환경에서 예상치 못한 버그를 초래할 수 있다.

    4. 접근 제어를 강화하는 방법

    (1) Property 데코레이터 활용

    Python에서는 @property 데코레이터를 활용하여 필드의 직접 접근을 차단하고, getter/setter 메서드를 통해 안전한 접근을 유도할 수 있다.

    class MyClass:
        def __init__(self, name):
            self.__name = name
    
        @property
        def name(self):
            return self.__name
    
        @name.setter
        def name(self, value):
            if isinstance(value, str):
                self.__name = value
            else:
                raise ValueError("Name must be a string")
    

    이렇게 하면 name 속성에 대한 직접 접근을 차단하고, 올바른 데이터 타입만 설정할 수 있도록 강제할 수 있다.

    (2) ABC 모듈을 이용한 강제 인터페이스 적용

    추상 클래스(ABC 모듈)를 활용하여 인터페이스를 강제하는 것도 하나의 방법이다.

    from abc import ABC, abstractmethod
    
    class AbstractClass(ABC):
        @abstractmethod
        def method(self):
            pass
    

    이제 AbstractClass를 상속받는 모든 클래스는 method()를 반드시 구현해야 한다.

    5. 결론

    Python에서는 private, protected, public 접근 제한이 강제되지 않지만, 네이밍 컨벤션과 @property 데코레이터 등을 활용하여 일정 부분 보완할 수 있다. 그러나 강력한 캡슐화가 필요한 경우, Java 같은 언어가 더 적합할 수 있다.

    Python이 접근 제어를 느슨하게 한 이유는 유연성과 개발자의 자율성을 보장하기 위해서다. 하지만 이를 효과적으로 활용하려면 팀원 간의 명확한 코드 컨벤션이 필수적이다.