ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Python getter setter property
    Python 2022. 9. 28. 16:19

    @property 데코레이터에 대해 알아보자

    그전에 선행으로 getter와 setter의 개념부터 알아보자

    class User:
        def __init__(self, name, age):
            self.name = name
            self.age = age
            
    
    first_user = User(name="루키", age=12)
    
    print(first_user.name) # 루키
    
    print(first_user.age) # 12
    
    first_user.age = first_user.age + 16
    
    print(first_user.age) # 28

    이런 간단한 구조의 클래스가 있을 때 파이썬에서는 클래스의 인스턴스를 생성 후 필드 값을 읽거나 쓰는 것에 제약이 없다.

    객체지향을 처음 공부하며 느낀 점 중 하나이다.

    캡슐화로 외부에서 접근을 막기 위해 정보 은닉으로 private로 설정한다고 했는데 파이썬 클래스에는 모두 공개되어 있는데 숨길 방법이 없나 라는 생각이 들었다.

     

    그런 부분에서 찾은 게 getter와 setter이다.

    클래스 인스턴스 내부 데이터를 보호하기 위해서 접근용 메서드를 작성하는 것이며 객체 지향 프로그래밍에서 흔히 볼 수 있는 패턴이다.

    예시에 getter setter를 적용시켜보자

    class User:
        def __init__(self, name, age):
            self.name = name
            self.set_age(age)
    
        def get_age(self):
            return self._age
    
        def set_age(self, age):
            if age < 0:
                raise ValueError("age value must be positive integer")
            self._age = age
                
    first_user = User(name="루키", age=12)
    
    print(first_user.get_age()) # 12
    
    first_user.set_age(age=-10) # ValueError: age value must be positive integer

    여기서 앞에 _ 하나가 붙는 이유는 어떤 제약이 걸린 것이 아니라 파이썬의 약속이다 _로 시작하는 변수는 외부에서 접근하지 않겠다 즉 private라는 뜻이다.

     

    그렇다면 처음에 설명한 @property는 무엇일까?

    이제 클래스의 인스턴스에 있는 나이를 읽거나 쓰려면 getter, setter 메서드를 사용해야 한다.

    하지만 기존의 필드명으로 바로 사용할 때보다는 코드가 깔끔하지 못하다.

    @property는 메서드를 마치 필드명처럼 사용할 수 있게 해 준다.

    class User:
        def __init__(self, name, age):
            self.name = name
            self._age = age
        
        @property
        def age(self):
            return self._age
    
        @age.setter
        def age(self, age):
            if age < 0:
                raise ValueError("age value must be positive integer")
            self._age = age
                
    first_user = User(name="루키", age=12)
    
    print(first_user.age) # 12
    
    first_user.age = 10
    
    print(first_user.age) # 10
    
    first_user.age = -1 # ValueError: age value must be positive integer

    이런 결과로 출력이 될 것이다.

     

    Django model에서도 사용하게 된다.

    위의 클래스가 django 모델 클래스라고 가정해보자

    from django.db import models
    
    class User(models.Model):
        name = models.CharField(
            verbose_name="이름",
            help_text="유저의 이름입니다.",
            max_length=20,
        )
        age = models.PositiveIntegerField(
            verbose_name="나이",
            help_text="유저의 나이입니다.",
            default=0,
        )
    
        @property
        def information(self):
            return f"{self.name} {self.age}세"
            
    
    user = User.objects.get(name="루키")
    user.information

    위와 같이 메서드를 필드명처럼 사용 가능하게 함을 이용하여 사용하고 있다

    나는 typing protocol에서 자주 활용하고 있다.

    'Python' 카테고리의 다른 글

    Python AES256 암호화, 복호화  (0) 2022.12.22
    파이썬 오버로딩과 오버라이딩  (2) 2022.11.10
    [lambda x: i * x for i in range(4)]  (1) 2022.11.07
    Python 패키징의 역사  (0) 2022.10.12
    Python Celery  (0) 2022.10.06

    댓글

Designed by Tistory.