본문 바로가기
Python Object-oriented Programming

properties

by 자동매매 2023. 4. 4.

출처: https://www.pythontutorial.net/python-oop/python-properties/

Introduction to class properties

 

다음은  이름과 나이라는 가지 속성 있는  Person  클래스를 정의하고 Person 클래스의 인스턴스를 만듭니다.

 

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age


john = Person('John', 18)

 

age  Person 클래스의 인스턴스 속성이므로 다음과 같이 값을 할당할 있습니다.

 

john.age = 19

 

다음 할당도 기술적으로 유효합니다.

 

john.age = -1

 

그러나 나이는 의미 올바르지 않습니다.

나이가 0 또는 음수가 아닌지 확인하려면 if 문을 사용하여 다음과 같이 검사를 추가합니다.

 

age = -1
if age <= 0:
    raise ValueError('The age must be positive')
else:
    john.age = age

 

그리고 age 속성에 값을 할당 때마다이 작업을 수행해야합니다  . 이것은 반복적이고 유지 관리가 어렵습니다.

이러한 반복을 방지하려면 getter setter라는 쌍의 메서드를 정의할 있습니다.

 

Getter and setter

 

getter setter 메서드는 인스턴스 속성에 액세스하기 위한 인터페이스를 제공합니다.

  • getter는 속성의 값을 반환합니다.
  • setter가 속성에 대한 새 값을 설정합니다.

예제에서는 age 속성을 비공개 설정  하고(규칙에 따라) age 속성을 조작할 getter setter 정의할   있습니다  .

다음은 age property 대해 getter setter 있는   Person 클래스를 보여 줍니다.

 

class Person:
    def __init__(self, name, age):
        self.name = name
        self.set_age(age)

    def set_age(self, age):
        if age <= 0:
            raise ValueError('The age must be positive')
        self._age = age

    def get_age(self):
        return self._age

 

작동 방식.

Person 클래스  에서 set_age()  setter이고 get_age()  getter입니다. 규칙에 따라 게터와 세터의 이름은 get_<attribute>()   set_<attribute>()입니다.

set_age() 메서드에서 나이가 0보다 거나 같으면 ValueError 발생합니다. 그렇지 않으면 age 인수를 _age 속성에 할당  합니다.

 

def set_age(self, age):
    if age <= 0:
        raise ValueError('The age must be positive')
    self._age = age

 

get_age()메소드는 _age 속성 값을 반환합니다.

 

def get_age(self):
    return self._age

 

__init__()  메서드  에서 set_age() setter 메서드를 호출하여 _age 속성을 초기화합니다.

 

def __init__(self, name, age):
    self.name = name
    self.set_age(age)

 

다음은 age 속성에 잘못된 값을 할당하려고 시도합니다.

 

john = Person('John', 18)
john.set_age(-19)

 

그리고 파이썬은 예상대로 ValueError 발행했습니다  .

 

ValueError: The age must be positive

 

이 코드는 잘 작동합니다. 그러나 이전 버전과의 호환성 문제가 있습니다. ( age와 _age )
잠시 동안 Person 클래스를 릴리스했고 다른 개발자가 이미 사용하고 있다고 가정합니다. 이제 getter와 setter를 추가하면 Person을 사용하는 모든 코드가 더 이상 작동하지 않습니다.

 

이전 버전과의 호환성을 유지하면서 getter setter 메서드를 정의하려면 property() 클래스를 사용할 있습니다.

 

The Python property class

 

property 클래스는 property 개체를 반환합니다. property() 클래스의 구문은 다음과 같습니다.

 

property(fget=None, fset=None, fdel=None, doc=None)

 

property()에는  다음과 같은 매개 변수가 있습니다.

  • fget 속성의 값을 가져오는 함수, 또는 getter 메서드
  • fset  속성의 값을 설정하는 함수, 또는 setter 메서드
  • fdel  속성을 삭제하는 함수
  • doc  docstring(주석)

 

다음은 property() 함수를  사용하여 Person 클래스의 age 속성을  정의합니다.

 

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def set_age(self, age):
        if age <= 0:
            raise ValueError('The age must be positive')
        self._age = age

    def get_age(self):
        return self._age

    age = property(fget=get_age, fset=set_age)

 

Person 클래스에서는 property() 호출하여 property 객체를 만들고  property 객체를 age 속성에 할당합니다.

age 인스턴스 속성이 아니라 클래스 속성입니다.

 

다음은 Person.age property 개체임을  보여 줍니다.

 

print(Person.age)

Output:

<property object at 0x000001F5F5149180>

 

다음은 Person 클래스의 인스턴스를 만들고 age성에 액세스합니다.

 

john = Person('John', 18)

 

john.__dict__  john 객체의 인스턴스 속성을 저장합니다. 다음은 john.__dict__ 내용을 보여줍니다  .

 

print(john.__dict__)

Output:

{'_age': 18, 'name': 'John'}

 

출력에서 명확하게 있듯이 john.__dict__에는 age 속성이 없습니다.( _age 존재 )

다음은  john 객체의 age 속성에 값을 할당합니다.

 

john.age = 19

 

경우 파이썬은 john.__dict__에서 age 속성을  먼저 찾습니다. 파이썬은 john.__dict__에서 age 속성을 찾지 못하기 때문에 Person.__dict__에서 age 속성을 찾습니다.

Person.__dict__ Person 클래스의  클래스 속성을 저장합니다. 다음은 Person.__dict__ 내용을 보여줍니다.

 

pprint(Person.__dict__)

Output:

mappingproxy({'__dict__': <attribute '__dict__' of 'Person' objects>,
              '__doc__': None,
              '__init__': <function Person.__init__ at 0x000002242F5B2670>,
              '__module__': '__main__',
              '__weakref__': <attribute '__weakref__' of 'Person' objects>,
              'age': <property object at 0x000002242EE39180>,
              'get_age': <function Person.get_age at 0x000002242F5B2790>,
              'set_age': <function Person.set_age at 0x000002242F5B2700>})

 

파이썬은 Person.__dict__에서 age 속성을  찾기 때문에, age property 객체에 값을 할당할 때 age 개체 호출합니다.

 

john.age = 19

 

파이썬은 fset 인수 할당된 함수인 set_age() 호출합니다.

마찬가지로, age property 객체에서 읽을 Python fget 인수 할당된 함수 get_age() 메서드를 실행합니다.

property()클래스를 사용하면 이전 버전과의 호환성을 유지하면서  클래스에 property를 추가 있습니다. 실제로는 속성을 먼저 정의합니다. 나중에 필요한 경우 클래스에 property를 추가할 있습니다.

 

전체 Code

 

from pprint import pprint


class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def set_age(self, age):
        if age <= 0:
            raise ValueError('The age must be positive')
        self._age = age

    def get_age(self):
        return self._age

    age = property(fget=get_age, fset=set_age)


print(Person.age)

john = Person('John', 18)
pprint(john.__dict__)

john.age = 19
pprint(Person.__dict__)

 

Summary

  • Python property() 클래스를 사용하여 클래스의 속성을 정의합니다.
  • 실제로는 속성을 먼저 정의합니다. 나중에 필요한 경우 클래스에 property를 추가하여 클래스 속성을 구현한다.

'Python Object-oriented Programming' 카테고리의 다른 글

delete-property  (0) 2023.04.04
readonly-property  (0) 2023.04.04
__del__ Method  (0) 2023.04.04
Dependency Inversion Principle  (0) 2023.04.04
__bool__ Method  (0) 2023.04.03

댓글