Python @property

2
post-thumbnail

파이썬에는 @property라는 데코레이터가 있습니다. @property를 사용하면 보다 pythonic 하게 코드를 작성할 수 있다는 장점이 있습니다. 또 어떤 상황에서 파이썬 @property 데코레이터를 사용하면 좋을까요 ?

@property를 알아가기전 접근제한자와 접근제한자가 등장한 배경인 캡슐화에 대해 간단하게 짚고 넘어가겠습니다.

캡슐화와 정보은닉

💡 캡슐화(Encapsulation): 객체의 속성과 행위를 하나로 묶고 실제 구현 내용 일부를 외부에 감추어 은닉

💊 캡슐화는 OOP의 특징 중 하나이며, 객체가 독립접으로 역할을 수행하기 위해 필요한 데이터와 기능을 한 곳에 패키징 한 것을 의미합니다. 패키징 된 다양한 기능은 캡슐과 같이 감싸져 있어 외부에서는 객체의 내부 구현을 알기 어렵습니다

💊 따라서 객체가 외부 공개를 허용한 일부의 인터페이스를 통해서만 객체에 접근 할 수 있습니다. 이를 통해 외부에 의한 중요 정보 탈취 및 무차별적인 객체 손상을 방지함으로써 정보은닉이 실현될 수 있습니다

💊 캡슐화를 통해 정보은닉이라는 하나의 목적을 달성하기 위해 접근제한자 를 이용하게 됩니다

접근제한자(Access Modifier)

🔒 접근제한자는 객체 정보은닉을 달성하기위해 객체에 존재하는 속성(필드)와 기능(메서드)에 대한 접근을 제한하는 역할을 수행합니다

🔒 접근제한자는 크게 private, default, protected, public 4가지가 있습니다. 일반적으로는 완전공개(public)와 완전비공개(private)를 주로 사용합니다. 자바의 경우 객체의 속성이나 매서드 앞에 접근제한자를 붙힘으로써 접근 제한 여부를 나타냅니다.

구분공개부분접근불가능
public같은 클래스 내에서 접근 가능없음
default패키지 공개자식 패키지 + 다른 패키지
protected패키지 공개 + 자식 패키지다른 패키지
private같은 클래스 공개다른 패키지, 다른 클래서

🔒 private로 보호된 필드는 외부에서 접근이 불가능합니다. 따라서 getter/setter method를 공개하여 외부에서 메소드를 통해 접근하도록 유도하여, 데이터를 우회하여 가져오거나 변경하며 객체의 무결성을 유지할 수 있습니다
🔒 특히 setter의 경우, 내부 속성의 값을 다시 설정할 때 특정 조건을 두어 재설정에 대한 안정성을 높힐 수 있습니다

python의 접근제한자

🔐 파이썬에는 별도의 접근제한자가 없지만(?) 있습니다(?)
🔐 public, private와 같은 명시적인 접근제한자는 없지만 네이밍 컨벤션을 통해 접근 여부를 표기합니다.

def __init__(self):
   self.public_property = 1
   self._protected_property = 1
   self.__privated_property = 1
구분공개부분접근불가능
public_property외부에서 접근 가능없음
_protected_property자기 자신 클래스와 상속된 클래스에서 사용 가능없음
__privated_property자기 자신 클래스외부에서 접근 불가능. 접근시 에러 발생

🔐 파이썬도 마찬가지로 접근 제한자가 지정되어 있는 변수들에 대한 getter/setter method를 생성하여 객체 내부의 속성을 읽거나 수정할 수 있습니다.

# getter / setter 선언
class GenG:
	def __init__(self):			# 객체 초기화
    	self.__jungle = 'peanut'
        
    def get_jungle(self):
        return self.__jungle
        
    def set_jungle(self, value):
        self.__jungle = value
    
# getter / setter 호출
gen_g = GenG()
print(gen_g.get_jungle()) # peanut

gen_g.set_jungle('youngjae')
print(gen_g.get_jungle()) # youngjae

Python의 @property

📍 파이썬의 @property 데코레이터는 getter/setter를 좀 더 우아하고 간결하게 표현할 수 있습니다

class GenG:
	def __init__(self):			# 객체 초기화
    	self.__jungle = 'peanut'
        
    @property
    def jungle(self):
        return self.__jungle
    
    @jungle.setter
    def jungle(self, value):
    	if not getattr(value, str):
        	raise '타입이 맞지 않습니다'
        self.__jungle = value
        
# getter / setter @property 호출
gen_g = GenG()
print(gen_g.jungle) # peanut

gen_g.jungle = 'youngjae'
print(gen_g.jungle) # youngjae

📍 기존 getter / setter과의 차이가 보이시나요 ?

  • 기존 getter / setter를 사용했을 때는 메소드()와 같이 getter / setter를 호출했다면 ex) 객체.get_jungle()
  • @property 데코레이터가 추가된 getter / setter의 경우 객체의 프로퍼티에 접근하듯이 내부 값을 호출합니다 ex) 객체.jungle

📍 여기서 주의할 점은 @property 가 @getter.setter보다 위에 있어야합니다

그렇다면 @property를 어떻게 활용하면 좋을까요 ?

🖋 기본적으로 @property의 목적은 객체의 프로퍼티에 직접 접근을 제한하기 위해 사용합니다

🖋 @property를 잘 활용하면 코드의 재활용성과 가독성이 높아지고, 유지보수가 용이합니다

🖋 코드를 작성하다보면 자연스럽게 조건 분기를 타는 경우가 많습니다. 하지만 조건 분기가 많아질수록 코드의 가독성이 떨어질 수 있는데 이때 @property를 잘 활용할 수 있습니다

🖋 2개 이상의 조건이나 단순 3항연산자로 표현하기에는 길어지거나, 그 의미를 파악하기 어려울 경우에 @property를 활용하면 보다 깔금한 코드를 작성할 수 있습니다

🖋 복잡한 연산이지만 별도의 매개변수 없이 객체 내부의 속성의 값으로만 연산하여 값을 도출 할 수 있을 때 @property를 활용하면 보다 직관적으로 나타낼 수 있습니다

참고자료

0개의 댓글