最近在撸这本书,
作个记录。
from abc import ABCMeta, abstractmethod # 引入ABCMeta和abstractmethod来定义抽象类和抽象方法 import time """ # version 1.0 class WaterHeater: # 热水器, 战胜寒冬的有利武器 def __init__(self): self.__observers = [] self.__temperature = 25 def get_temperature(self): return self.__temperature def set_temperature(self, temperature): self.__temperature = temperature print("当前温度是:" + str(self.__temperature) + " C") self.notifies() def notifies(self): for o in self.__observers: o.update(self) def add_observer(self, observer): self.__observers.append(observer) class Observer(metaclass=ABCMeta): # 洗澡模式和饮用模式的父类 @abstractmethod def update(self, water_heater): pass class WashingMode(Observer): # 该模式用于洗澡 def update(self, water_heater): if 50 <= water_heater.get_temperature() < 70: print("水已烧好,温度正好,可以来洗澡了。") class DrinkingMod(Observer): # 该模式用于饮用 def update(self, water_heater): if water_heater.get_temperature() >= 100: print("水已烧开,可以来饮用了。") """ # version 2.0 class Observable: # 被观察者的基类 def __init__(self): self.__observers = [] def add_observer(self, observer): self.__observers.append(observer) def remove_observer(self, observer): self.__observers.remove(observer) def notify_observers(self, observer=0): for o in self.__observers: o.update(self, observer) class WaterHeater(Observable): # 热水器, 战胜寒冬的有利武器 def __init__(self): super().__init__() self.__temperature = 25 def get_temperature(self): return self.__temperature def set_temperature(self, temperature): self.__temperature = temperature print("当前温度是:" + str(self.__temperature) + " C") self.notify_observers() class Observer(metaclass=ABCMeta): # 观察者的基类 @abstractmethod def update(self, observable, observer): pass class WashingMode(Observer): # 该模式用于洗澡 def update(self, observable, observer): if isinstance(observable, WaterHeater) and 50 <= observable.get_temperature() < 70: print("水已烧好,温度正好,可以来洗澡了。") class DrinkingMod(Observer): # 该模式用于饮用 def update(self, observable, observer): if isinstance(observable, WaterHeater) and observable.get_temperature() >= 100: print("水已烧开,可以来饮用了。") def test_water_heater(): heater = WaterHeater() washing_observer = WashingMode() drinking_observer = DrinkingMod() heater.add_observer(washing_observer) heater.add_observer(drinking_observer) heater.set_temperature(20) heater.set_temperature(40) heater.set_temperature(60) heater.set_temperature(80) heater.set_temperature(100) test_water_heater() # 实践应用:登陆异常的检测与提醒 class Account(Observable): def __init__(self): super().__init__() self.__latest_ip = {} self.__latest_region = {} def __get_region(self, ip): ip_regions = { '101.47.18.9': '浙江省杭州市', '67.218.147.69': '美国洛彬矶' } region = ip_regions.get(ip) return '' if region is None else region def __is_long_distance(self, name, region): latest_region = self.__latest_region.get(name) return latest_region is not None and latest_region != region def login(self, name, ip, login_time): region = self.__get_region(ip) if self.__is_long_distance(name, region): self.notify_observers({'name': name, 'ip': ip, 'region': region, 'time': login_time}) self.__latest_region[name] = region self.__latest_ip[name] = ip class SmsSender(Observer): def update(self, observable, observer): print("[短信发送] {} 您好,检测到您的帐户可能登陆异常,最近一次登陆信息:\n 登陆地区:{} 登陆ip: {} 登陆时间:{}" .format(observer["name"], observer["region"], observer["ip"], observer["time"])) class MailSender(Observer): def update(self, observable, observer): print("[邮件发送] {} 您好,检测到您的帐户可能登陆异常,最近一次登陆信息:\n 登陆地区:{} 登陆ip: {} 登陆时间:{}" .format(observer["name"], observer["region"], observer["ip"], observer["time"])) def test_login(): account = Account() account.add_observer(SmsSender()) account.add_observer(MailSender()) account.login("Tony", '101.47.18.9', time.time()) account.login("Tony", '67.218.147.69', time.time()) account.login("Tony", '101.47.18.9', time.time()) test_login()
C:\Python36\python.exe C:/Users/Sahara/PycharmProjects/test/python_search.py 当前温度是:20 C 当前温度是:40 C 当前温度是:60 C 水已烧好,温度正好,可以来洗澡了。 当前温度是:80 C 当前温度是:100 C 水已烧开,可以来饮用了。 [短信发送] Tony 您好,检测到您的帐户可能登陆异常,最近一次登陆信息: 登陆地区:美国洛彬矶 登陆ip: 67.218.147.69 登陆时间:1565402412.372697 [邮件发送] Tony 您好,检测到您的帐户可能登陆异常,最近一次登陆信息: 登陆地区:美国洛彬矶 登陆ip: 67.218.147.69 登陆时间:1565402412.372697 [短信发送] Tony 您好,检测到您的帐户可能登陆异常,最近一次登陆信息: 登陆地区:浙江省杭州市 登陆ip: 101.47.18.9 登陆时间:1565402412.372697 [邮件发送] Tony 您好,检测到您的帐户可能登陆异常,最近一次登陆信息: 登陆地区:浙江省杭州市 登陆ip: 101.47.18.9 登陆时间:1565402412.372697 Process finished with exit code 0