#!/usr/bin/env PYTHONHASHSEED=1234 python3 # Copyright 2014-2019 Brett Slatkin, Pearson Education Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Reproduce book environment import random random.seed(1234) import logging from pprint import pprint from sys import stdout as STDOUT # Write all output to a temporary directory import atexit import gc import io import os import tempfile TEST_DIR = tempfile.TemporaryDirectory() atexit.register(TEST_DIR.cleanup) # Make sure Windows processes exit cleanly OLD_CWD = os.getcwd() atexit.register(lambda: os.chdir(OLD_CWD)) os.chdir(TEST_DIR.name) def close_open_files(): everything = gc.get_objects() for obj in everything: if isinstance(obj, io.IOBase): obj.close() atexit.register(close_open_files) # Example 1 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( 'Grade must be between 0 and 100') self._grade = value # Example 2 galileo = Homework() galileo.grade = 95 assert galileo.grade == 95 # Example 3 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( 'Grade must be between 0 and 100') # Example 4 @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 galileo = Exam() galileo.writing_grade = 85 galileo.math_grade = 99 assert galileo.writing_grade == 85 assert galileo.math_grade == 99 # Example 5 class Grade: def __get__(self, instance, instance_type): pass def __set__(self, instance, value): pass class Exam: # Class attributes math_grade = Grade() writing_grade = Grade() science_grade = Grade() # Example 6 exam = Exam() exam.writing_grade = 40 # Example 7 Exam.__dict__['writing_grade'].__set__(exam, 40) # Example 8 exam.writing_grade # Example 9 Exam.__dict__['writing_grade'].__get__(exam, Exam) # Example 10 class Grade: def __init__(self): self._value = 0 def __get__(self, instance, instance_type): return self._value def __set__(self, instance, value): if not (0 <= value <= 100): raise ValueError( 'Grade must be between 0 and 100') self._value = value # Example 11 class Exam: math_grade = Grade() writing_grade = Grade() science_grade = Grade() first_exam = Exam() first_exam.writing_grade = 82 first_exam.science_grade = 99 print('Writing', first_exam.writing_grade) print('Science', first_exam.science_grade) # Example 12 second_exam = Exam() second_exam.writing_grade = 75 print(f'Second {second_exam.writing_grade} is right') print(f'First {first_exam.writing_grade} is wrong; ' f'should be 82') # Example 13 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( 'Grade must be between 0 and 100') self._values[instance] = value # Example 14 from weakref import WeakKeyDictionary class Grade: def __init__(self): self._values = WeakKeyDictionary() 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( 'Grade must be between 0 and 100') self._values[instance] = value # Example 15 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 {first_exam.writing_grade} is right') print(f'Second {second_exam.writing_grade} is right')