Descriptor vs Property

표현을 하자면 Descriptor는 low level로 보고 property는 high level로 본다. 그 이유는 property는 더 사용하기 쉽고 읽기 쉬워 보이나 재사용성이 낮기 떄문이다.

Descriptor

  1. 상황에 맞는 메소드 구현을 통한 객체 지향 프로그래밍 구현
  2. Property와 달리 reuse(재사용) 가능
  3. ORM Framework 사용

예제

# Ex1
# Descript 예제(1)
import os

class DirectoryFileCount:
    def __get__(self, instance, owner=None):
        # print(os.listdir(instance.dirname))
        return len(os.listdir(instance.dirname))

class DirectoryPath:
    # Descriptor instance
    size = DirectoryFileCount()

    def __init__(self, dirname):
        self.dirname = dirname

# 현재 경로
s = DirectoryPath('./')
# 이전 경로
g = DirectoryPath('../')

# 헷갈릴 떄 출력 용도
print(dir(DirectoryPath))
print(DirectoryPath.__dict__)

print(s.size)
print(g.size)

print(dir(s))
print(s.__dict__)

디렉토리의 파일 갯수를 구하는 기능을 만든다. Count 해주는 클래스를 재사용할 수 있다는 점이 핵심이다.

로그 예제

# Ex2
# Descript 예제 2 = Log

import logging

logging.basicConfig(
    format='%(asctime)s %(message)s',
    level=logging.INFO,
    datefmt='%Y-%m-%d %H:%M:%S'
)

class LoggedScoreAccess:
    def __init__(self, value=50):
        self.value = value

    def __get__(self, instance, owner=None):
        logging.info('Accessing %r giving %r', 'score', self.value)
        return self.value

    def __set__(self, instance, value):
        logging.info('Updating %r giving %r', 'score', self.value)
        self.value = value

class Student:
    # Descriptor instance
    score = LoggedScoreAccess()

    def __init__(self, name):
        # Regular instance attribute
        self.name = name

s1 = Student('Kim')
s2 = Student('Lee')

# 점수 확인
print('Ex2 > ', s1.score)
s1.score += 20
print('Ex2 > ', s1.score)

print('Ex2 > ', s2.score)
s2.score += 30
print('Ex2 > ', s2.score)

print('Ex2 > ', vars(s1))
print('Ex2 > ', vars(s2))
print('Ex2 > ', s1.__dict__)
print('Ex2 > ', s2.__dict__)