[코드잇] 쉽게 배우는 파이썬 문법 - 프로퍼티(Property)

코드잇

안녕하세요, 온라인 코딩 스쿨 코드잇입니다.

이번 시간에는 파이썬에서 사용되는 프로퍼티(Property)라는 기능을 배워볼게요. 일단 프로퍼티가 무엇인지 배우기 전에 다음 코드를 살펴볼게요.

class Citizen:
    def __init__(self, age_value):
        self._age = age_value

    def get_age(self):
        print('나이를 리턴합니다.')
        return self._age

    def set_age(self, age_value):
        print('나이를 새로 설정합니다.')
        self._age = age_value

이 코드는 시민을 나타내는 Citizen 클래스입니다. Citizen 클래스는

- _age라는 나이를 나타내는 인스턴스 변수와

- get_age, set_age라는 인스턴스 메소드를 가지고 있는데요.

두 메소드를 살펴보니 get_age 메소드는 _age 의 값을 리턴하고, set_age 메소드는 _age의 값을 설정하네요. 여기까진 별로 어렵지 않죠? 여기서 왜 변수 이름을 그냥 age라고 하지 않고 굳이 맨 앞에 밑줄 하나를 붙여서 _age로 썼는지 궁금하실 분도 계실 텐데요. 그 이유는 파이썬의 캡슐화라는 것 때문입니다. 캡슐화는 클래스의 속성을 바깥에서 직접 접근하지 못하도록 하는 것인데요. 혹시 캡슐화가 무엇인지 자세히 알고 싶으신 분은 곧 코드잇에서 열릴 객체 지향 프로그래밍 수업을 참고해주세요.

당장 캡슐화를 몰라도 일단은 이 코드의 내용만 이해하시면 됩니다.

Citizen 클래스를 한번 사용해봅시다.

class Citizen:
    def __init__(self, age_value):
        self._age = age_value

    def get_age(self):
        print('나이를 리턴합니다.')
        return self._age

    def set_age(self, age_value):
        print('나이를 새로 설정합니다.')
        self._age = age_value


citizen = Citizen(20)
print(citizen.get_age())
citizen.set_age(25)
print(citizen.get_age())

이 코드를 실행하면

나이를 리턴합니다.
20
나이를 새로 설정합니다.
나이를 리턴합니다.
25

이렇게 잘 실행됩니다.

자, 이제부터 본격적으로 프로퍼티(Property)를 설명해드릴게요. 프로퍼티는 사실 데코레이터 함수입니다. 데코레이터가 뭔지는 이전에 2개의 게시글을 통해 설명해드렸는데요. 기억이 안 나시면 다시 아래 링크를 통해 글을 읽고 와주세요.

파이썬에서 데코레이터(Decorator)란??

파이썬 데코레이터(Decorator)에 파라미터 넣기

아래는 프로퍼티를 적용한 Citizen 클래스입니다. 코드를 보시죠.

class Citizen:
    def __init__(self, age_value):
        self.age = age_value

    @property
    def age(self):
        print('나이를 리턴합니다.')
        return self._age

    @age.setter
    def age(self, age_value):
        print('나이를 새로 설정합니다.')
        self._age = age_value

Citizen 클래스가 뭔가 좀 변했죠? 일단 get_age , set_age 메소드의 내용은 그대론데 그 헤더(header)들이 변했네요. 하나씩 살펴봅시다. 먼저 이 부분은 무슨 뜻일까요?

@property
def age(self):
    print('나이를 리턴합니다.')
    return self._age

이 함수의 바디(body) 부분은 get_age 의 바디와 같습니다. 같은데 그 헤더(header) 부분은 좀 특이하네요. 함수의 이름이 age 이고 그 위에 @property 이렇게 데코레이터 표시가 붙어있습니다. 이 @property가 우리가 배울 프로퍼티라는 겁니다.

저렇게 프로퍼티가 이름 위에 붙은 메소드는 조금 특이한 방식으로 기능이 변합니다. 일단 아래 코드처럼 프로퍼티가 적용된 Citizen 클래스를 한번 사용해볼까요?

class Citizen:
    def __init__(self, age_value):
        self._age = age_value

    @property
    def age(self):
        print('나이를 리턴합니다.')
        return self._age

    @age.setter
    def age(self, age_value):
        print('나이를 새로 설정합니다.')
        self._age = age_value


citizen = Citizen(20)
print(citizen.age)

맨 마지막 줄에

print(citizen.age)

이 부분은 age 라는 변수의 값을 출력하겠다는 뜻입니다. 그런데 지금 Citizen 클래스에는 _age 변수는 있어도 age 변수는 없습니다. 코드를 실행하면 에러가 날 것 같은데.. 한번 실행해볼까요?

나이를 리턴합니다.
20

어! 그런데 에러가 발생하지 않고 잘 실행됩니다. 그리고 그 결과를 보면 바뀌기 전의 Citizen 클래스의 메소드 중 이름 위에 @property 표시가 붙어있던 age 메소드가 실행된 것 같습니다. 사실 이것이 프로퍼티의 기능입니다.

Citizen 클래스의 내용 중 이 부분은

@property
def age(self):
  print('나이를 리턴합니다.')
  return self._age

이제

citizen.age 같은 코드를 실행할 때 새로운 의미를 부여한다는 뜻입니다. 원래 이 부분은

Citizen 이라는 인스턴스의 age 라는 변수의 값을 가져오겠다는 뜻이죠?

하지만 저렇게 age라는 함수 이름 위에 프로퍼티를 붙이면 citizen.age 코드의 의미가 Citizen 인스턴스의 age라는 메소드를 실행하겠다는 것으로 바뀝니다.

지금 age 메소드는 원래 있었던 get_age 메소드와 그 내용이 같습니다. 맨 처음 Citizen 클래스의 get_age 메소드와 바뀐 Citizen 클래스의 @property가 붙은 age 메소드를 비교해보세요. 바디가 같다는 걸 확인하실 수 있을 거에요.

@property 를 붙인 메소드는 일반적으로 어떤 인스턴스 변수에 대한 getter 메소드임을 나타냅니다.

그러니까 정리하자면

지금 age라는 메소드는 _age라는 인스턴스 변수의 getter 역할을 하는 메소드이고

원래 우리가 변수의 값을 가져올 때 사용하는 citizen.age 같은 구문이 프로퍼티(@property)로 인해 age메소드를 실행하는 걸로 의미가 바뀌어 실행된다는 겁니다.

프로퍼티를 처음 접하신 분은 이 원리가 굉장히 낯설 수도 있습니다. 앞으로 이 블로그에서 파이썬의 프로퍼티에 대해서 자세히 알려드릴게요. 일단 방금까지 설명드린 부분을 이해하고 익숙해지도록 노력해보세요. 그래야 다음 내용으로 넘어갈 수 있습니다. 아직 Citizen 클래스에서 이 부분

@age.setter
def age(self, age_value):
    print('나이를 새로 설정합니다.')
    self._age = age_value

의 의미는 설명드리지 않았는데요.

다음 게시글에서 이 부분의 의미와 프로퍼티를 왜 사용하는지를 알려드릴게요. 파이썬의 프로퍼티를 제대로 마스터하고 싶으시면 코드잇 블로그 구독 잊지마세요~!

기업문화 엿볼 때, 더팀스

로그인

/