Skip to content

Latest commit

ย 

History

History
159 lines (123 loc) ยท 4.98 KB

File metadata and controls

159 lines (123 loc) ยท 4.98 KB

46. ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ @property ๋ฉ”์†Œ๋“œ๋ฅผ ๋งŒ๋“ค๋ ค๋ฉด ๋””์Šคํฌ๋ฆฝํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜๋ผ

1. @property ๋‚ด์žฅ ๊ธฐ๋Šฅ์˜ ๋‹จ์ 

  • ์žฌ์‚ฌ์šฉ์„ฑ ๋–จ์–ด์ง
  • @property๊ฐ€ ๋ฐ์ฝ”๋ ˆ์ด์…˜ํ•˜๋Š” ๋ฉ”์†Œ๋“œ๋ฅผ ๊ฐ™์€ ํด๋ž˜์Šค์— ์†ํ•˜๋Š” ์—ฌ๋Ÿฌ ์• ํŠธ๋ฆฌ๋ทฐํŠธ๋กœ ์‚ฌ์šฉ ๋ถˆ๊ฐ€
class Homework:
    def __init__(self):
        self._grade = 0

    @property
    def grade(self):
        return self._grade

    @grade.setter
    def grade(self, value):
        if not (0 <= value <= 100):
            raise ValueError('์ ์ˆ˜๋Š” 0๊ณผ 100 ์‚ฌ์ด์ž…๋‹ˆ๋‹ค')
        self._grade = value

galileo = Homework()
galileo.grade = 95
class Exam:
    def __init__(self):
        self._writing_grade = 0
        self._math_grade = 0

    @staticmethod
    def _check_grade(value):
        if not (0 <= value <= 100):
            raise ValueError('์ ์ˆ˜๋Š” 0๊ณผ 100 ์‚ฌ์ด์ž…๋‹ˆ๋‹ค')

    @property
    def writing_grade(self):
        return self._writing_grade
        
    @writing_grade.setter
    def writing_grade(self, value):
        self._check_grade(value)
        self._writing_grade = value
        
    @property
    def math_grade(self):
        return self._math_grade
        
    @math_grade.setter
    def math_grade(self, value):
        self._check_grade(value)
        self._math_grade = value
  • Exam ํด๋ž˜์Šค์™€ ๊ฐ™์ด ๊ณ„์† ํ™•์žฅํ•˜๋‹ค๋ณด๋ฉด ์‹œํ—˜ ๊ณผ๋ชฉ์„ ์ด๋ฃจ๋Š” ๊ฐ ๋ถ€๋ถ„๋งˆ๋‹ค ์ƒˆ๋กœ์šด @property ๋ฅผ ์ง€์ •ํ•˜๊ณ  ๊ด€๋ จ ๊ฒ€์ฆ ๋ฉ”์†Œ๋“œ๋ฅผ ์ž‘์„ฑํ•ด์•ผ ํ•จ
  • ์ˆ™์ œ๋‚˜ ์‹œํ—˜ ์„ฑ์  ์ด์™ธ์˜ ๋ถ€๋ถ„์— ๋ฐฑ๋ถ„์œจ ๊ฒ€์ฆ์„ ํ•˜๊ณ  ์‹ถ์€ ๊ฒฝ์šฐ ๋˜‘๊ฐ™์ด ๊ฒ€์ฆ๋Œ€์ƒ_grade ์— ๋Œ€ํ•œ setter ๋ฉ”์†Œ๋“œ๋ฅผ ๋‹ค์‹œ ๋งŒ๋“ค์–ด์•ผ ํ•จ

2. ๋””์Šคํฌ๋ฆฝํ„ฐ

  • ๋””์Šคํฌ๋ฆฝํ„ฐ ํ”„๋กœํ† ์ฝœ์€ ํŒŒ์ด์„  ์–ธ์–ด์—์„œ ์• ํŠธ๋ฆฌ๋ทฐํŠธ ์ ‘๊ทผ์„ ํ•ด์„ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ •์˜
  • ๋””์Šคํฌ๋ฆฝํ„ฐ ํด๋ž˜์Šค๋Š” __get__, __set__ ๋ฉ”์†Œ๋“œ ์ œ๊ณต
  • ๊ฐ™์€ ๋กœ์ง์„ ํ•œ ํด๋ž˜์Šค ์•ˆ์— ์†ํ•œ ์—ฌ๋Ÿฌ ๋‹ค๋ฅธ ์• ํŠธ๋ฆฌ๋ทฐํŠธ์— ์ ์šฉ ๊ฐ€๋Šฅ
  • ๋””์Šคํฌ๋ฆฝํ„ฐ๊ฐ€ ๋ฏน์Šค์ธ ๋ณด๋‹ค ๋‚˜์Œ
class Grade:
    def __get__(self, instance, instance_type):
        ...
    def __set__(self, instance, value):
        ...

class Exam:
    # ํด๋ž˜์Šค ์• ํŠธ๋ฆฌ๋ทฐํŠธ
    math_grade = Grade()
    writing_grade = Grade()
    science_grade = Grade()

exam = Exam()
exam.writing_grade = 40
  • exam.writing_grade ์— 40 ์„ ๋Œ€์ž…ํ•˜๊ฒŒ ๋˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํ•ด์„๋จ
Exam.__dict__['writing_grade'].__set__(exam, 40)
  • exam.writing_grade ๋ฅผ ์ฝ๊ฒŒ๋˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํ•ด์„๋จ
Exam.__dict__['writing_grade'].__get__(exam, Exam)
  • ํ•ด๋‹น ๋™์ž‘์€ object ์˜ __getattribute__ ๋ฉ”์†Œ๋“œ

    • Exam ์ธ์Šคํ„ด์Šค์— writing_grade ์ด๋ฆ„์˜ ์• ํŠธ๋ฆฌ๋ทฐํŠธ๊ฐ€ ์—†์œผ๋ฉด python ์—์„œ Exam ํด๋ž˜์Šค์˜ ์• ํŠธ๋ฆฌ๋ทฐํŠธ๋ฅผ ๋Œ€์‹  ์‚ฌ์šฉ
    • ํด๋ž˜์Šค์˜ ์• ํŠธ๋ฆฌ๋ทฐํŠธ๊ฐ€ __get__, __set__ ๋ฉ”์†Œ๋“œ๊ฐ€ ์ •์˜๋œ ๊ฐ์ฒด๋ผ๋ฉด python ์€ ๋””์Šคํฌ๋ฆฝํ„ฐ ํ”„๋กœํ† ์ฝœ์„ ๋”ฐ๋ฅด๋„๋ก ๊ฒฐ์ •ํ•จ
  • ํ˜„์žฌ ๊ตฌํ˜„์€ ๋ชจ๋“  Exam ์ธ์Šคํ„ด์Šค๊ฐ€ ์• ํŠธ๋ฆฌ๋ทฐํŠธ๋ฅผ ๊ณต์œ ํ•˜์—ฌ ๊ด€๋ฆฌ์— ๋ถˆํŽธ, ์•„๋ž˜์™€ ๊ฐ™์ด ์ˆ˜์ •

class Grade:
    def __init__(self):
        self._values = {}

    def __get__(self, instance, instance_type):
        if instance is None:
            return self
        return self._values.get(instance, 0)

    def __set__(self, instance, value):
        if not (0 <= value <= 100):
            raise ValueError('์ ์ˆ˜๋Š” 0๊ณผ 100 ์‚ฌ์ด์ž…๋‹ˆ๋‹ค')
        self._values[instance] = value
  • __set__ ๋ฉ”์†Œ๋“œ์—์„œ ํ”„๋กœ๊ทธ๋žจ์ด ์‹คํ–‰๋˜๋Š” ๋™์•ˆ ๋ชจ๋“  Exam ์ธ์Šคํ„ด์Šค์— ๋Œ€ํ•œ ์ฐธ์กฐ๋ฅผ _value ๊ฐ€ ์ €์žฅ

  • ๋ฌธ์ œ

    • ์ธ์Šคํ„ด์Šค์— ๋Œ€ํ•œ ์ฐธ์กฐ ์นด์šดํ„ฐ๊ฐ€ ์ ˆ๋Œ€๋กœ 0์ด ๋  ์ˆ˜ ์—†์Œ
    • garbage collector๊ฐ€ ์ธ์Šคํ„ด์Šค ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์žฌํ™œ์šฉํ•˜์ง€ ๋ชปํ•จ
    • ๋ˆ„์ˆ˜ ๋ฐœ์ƒ
  • ํ•ด๊ฒฐ๋ฐฉ์•ˆ

    • weakref ๋‚ด์žฅ ๋ชจ๋“ˆ ์‚ฌ์šฉ
    • WeakKeyDictionary ํด๋ž˜์Šค ์ œ๊ณต, _value ์— ์‚ฌ์šฉํ•˜๋„๋ก ์ˆ˜์ •
      • ๋”•์…”๋„ˆ๋ฆฌ์— ๊ฐ์ฒด๋ฅผ ์ €์žฅํ•  ๋•Œ ์•ฝํ•œ ์ฐธ์กฐ(weak reference)๋ฅผ ์‚ฌ์šฉํ•จ
      • garbage collector ๋Š” ์•ฝํ•œ ์ฐธ์กฐ๋กœ๋งŒ ์ฐธ์กฐ๋œ ๊ฐ์ฒด๊ฐ€ ์‚ฌ์šฉ ์ค‘์ธ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์žฌํ™œ์šฉํ•  ์ˆ˜ ์žˆ์Œ
      • WeakKeyDictionary ์— ์ €์žฅ๋œ Exam ์ธ์Šคํ„ด์Šค๊ฐ€ ๋” ์ด์ƒ ์“ฐ์ด์ง€ ์•Š์œผ๋ฉด garbage collector ๊ฐ€ ํ•ด๋‹น ๋ฉ”๋ชจ๋ฆฌ ์žฌํ™œ์šฉ ๊ฐ€๋Šฅ
from weakref import WeakKeyDictionary

class Grade:
    def __init__(self):
        self._values = WeakKeyDictionary()
        
    def __get__(self, instance, instance_type):
        ...
                
    def __set__(self, instance, value):
        ...

class Exam:
    math_grade = Grade()
    writing_grade = Grade()
    science_grade = Grade()
    
first_exam = Exam()
first_exam.writing_grade = 82
second_exam = Exam()
second_exam.writing_grade = 75
print(f'์ฒซ ๋ฒˆ์งธ ์“ฐ๊ธฐ ์ ์ˆ˜ {first_exam.writing_grade} ๋งž์Œ')
print(f'๋‘ ๋ฒˆ์งธ ์“ฐ๊ธฐ ์ ์ˆ˜ {second_exam.writing_grade} ๋งž์Œ')

>>>
์ฒซ ๋ฒˆ์งธ ์“ฐ๊ธฐ ์ ์ˆ˜ 82 ๋งž์Œ
๋‘ ๋ฒˆ์งธ ์“ฐ๊ธฐ ์ ์ˆ˜ 75 ๋งž์Œ