面向过程的设计思路
1,设计一个计算器,实现一些基本的操作,加减乘除运算,以及打印结果操作
- 定义一个变量来存储每次运算的结果 ```python result = 0
def first_value(v): global result result = v # 接收每次运算输入的第一个数值
def jia(n): global result result += n
def jian(n): global result result -= n
def cheng(n): global result result *= n
def show(): print(‘计算的结果为:%d’ %result)
first_value(1) jia(5) jian(3) cheng(6) show()
<a name="d096e49f"></a># 面向对象的设计思路<a name="2bac1f38"></a>## 通过【类属性】来操作运算结果- 通过类名来访问```pythonclass Caculator:__result = 0 # 为了不让外界操作这个类属性,即定义一个私有属性@classmethoddef first_values(cls,v): # 定义类方法,调用类属性,传递一个类名就可以了,这里使用了参数clscls.__result = v@classmethoddef jia(cls,n):cls.__result += n@classmethoddef jian(cls,n):cls.__result -= n@classmethoddef cheng(cls,n):cls.__result *= n@classmethoddef show(cls): # 由于最终要打印计算结果,且结果保存在私有属性中,外界无法访问,所以在内部提供一个方法来访问该私有属性print('计算的结果为:%d' %cls.__result)Caculator.first_values(10)Caculator.jia(5)Caculator.jian(3)Caculator.cheng(6)Caculator.show()
上述代码存在的问题:
- result是一个类属性,类属性是依赖类对象存在的,在内存中,每个类只会存在一份,所以只能计算一份结果,无法同时进行多个表达式的运算;
另外,当其他多个对象调用这个类属性的时候,调用和修改都是同一个属性的值,所以最终计算得到的结果都是同一个值;
通过【实例化】来操作运算结果
通过实例化对象来操作计算的结果,就是将result变成一个实例属性,一个实例就是一个计算器,不同的实例就是不同的计算器 ```python class Caculator:
def init(self,num):
self.__result = num # 初始化,输入计算前第一个数值
def jia(self,n):
self.__result += n
def jian(self,n):
self.__result -= n
def cheng(self,n):
self.__result *= n
def show(self):
print('计算的结果为:%d' %self.__result)
c1 = Caculator(5) # c1计算器
c1.jia(5)
c1.jian(3)
c1.cheng(6)
c1.show()
c2 = Caculator(6) # c2计算器
c2.jia(1)
c2.jian(3)
c2.cheng(6)
c2.show()
- 容错处理(对n和num进行判断,是否为整形)```pythonclass Caculator:def check_num(self,num): # 单独写一个方法,用于判断输入的数值是否为数值型if not isinstance(num,int):raise TypeError("当前这个数据有问题,应该为一个数值类型")def __init__(self,num):self.check_num(num) # 调用容错处理的方法self.__result = numdef jia(self,n):self.check_num(n) # 调用容错处理的方法self.__result += ndef jian(self,n):self.check_num(n) # 调用容错处理的方法self.__result -= ndef cheng(self,n):self.check_num(n) # 调用容错处理的方法self.__result *= ndef show(self):print('计算的结果为:%d' %self.__result)c1 = Caculator(2)c1.jia(6)c1.jian(4)c1.cheng(5)c1.show()
上述容错处理的代码中,在方法中又调用了容错处理的方法,破坏了原来的代码的单一原则,原本每个方法只负责加减乘除的操作,现在又增加了额外的功能,即破坏了代码
容错处理装饰器
```python class Caculator: def __check_num_zsq(func): # 重点,定义私有装饰器,避免外界调用或修改
def inner(self,n): # 重点,这里接收的参数和被装饰的方法所接收的参数一致if not isinstance(n,int):raise TypeError("当前这个数据有问题,应该为一个数值类型")return func(self,n) # 执行方法,这里就是执行下面加减乘除的方法return inner
@check_num_zsq def init__(self,num):
self.__result = num
@__check_num_zsq def jia(self,n):
self.__result += n
@__check_num_zsq def jian(self,n):
self.__result -= n
@__check_num_zsq def cheng(self,n):
self.__result *= n
def show(self):
print('计算的结果为:%d' %self.__result)
c1 = Caculator(2) c1.jia(6) c1.jian(4) c1.cheng(5) c1.show()
<a name="23c709c4"></a>## 嵌入播报功能- 如何嵌入```pythonimport win32com.clientclass Caculator:def __say(self,word): # 单独定义一个播报方法,播报的word = n或是numspeaker = win32com.client.Dispatch("SAPI.SpVoice") # 1,创建一个播报器对象speaker.Speak(word) # 2,通过播报器对象,直接播放相对应的语音字符串def __check_num_zsq(func): # 重点,定义私有装饰器,避免外界调用或修改def inner(self,n): # 重点,这里接收的参数和被装饰的方法所接收的参数一致if not isinstance(n,int):raise TypeError("当前这个数据有问题,应该为一个数值类型")return func(self,n) # 执行方法,这里就是执行下面加减乘除的方法return inner@__check_num_zsqdef __init__(self,num):self.__say(num)self.__result = num@__check_num_zsqdef jia(self,n):self.__say(n)self.__result += n@__check_num_zsqdef jian(self,n):self.__say(n)self.__result -= n@__check_num_zsqdef cheng(self,n):self.__say(n)self.__result *= ndef show(self):self.__say('计算的结果为:%d' %self.__result)print('计算的结果为:%d' %self.__result)c1 = Caculator(2)c1.jia(6)c1.jian(4)c1.cheng(5)c1.show()
播报装饰器 - 仅播报数字
import win32com.clientclass Caculator:def __say_zsq(func): # 重点,定义私有装饰器,避免外界调用或修改def inner(self,n):speaker = win32com.client.Dispatch("SAPI.SpVoice")speaker.Speak(n)return func(self,n)return innerdef __check_num_zsq(func): # 重点,定义私有装饰器,避免外界调用或修改def inner(self,n): # 重点,这里接收的参数和被装饰的方法所接收的参数一致if not isinstance(n,int):raise TypeError("当前这个数据有问题,应该为一个数值类型")return func(self,n) # 执行方法,这里就是执行下面加减乘除的方法return inner@__check_num_zsq@__say_zsq # 先验证,后播报def __init__(self,num):self.__result = num@__check_num_zsq@__say_zsqdef jia(self,n):self.__result += n@__check_num_zsq@__say_zsqdef jian(self,n):self.__result -= n@__check_num_zsq@__say_zsqdef cheng(self,n):self.__result *= ndef show(self):# self.__say('计算的结果为:%d' %self.__result)print('计算的结果为:%d' %self.__result)c1 = Caculator(2)c1.jia(6)c1.jian(4)c1.cheng(5)c1.show()
带参数的装饰器 - 符号和数字
import win32com.clientclass Caculator:def create_say(word = ''): # 定义一个函数,接收一个参数,函数内部就是一个装饰器,最终将这个装饰器返回def __say_zsq(func): # 装饰器def inner(self,n):speaker = win32com.client.Dispatch("SAPI.SpVoice")speaker.Speak(word + str(n))return func(self,n)return innerreturn __say_zsq # 将函数内部的装饰器返回出去def __check_num_zsq(func):def inner(self,n):if not isinstance(n,int):raise TypeError("当前这个数据有问题,应该为一个数值类型")return func(self,n)return inner@__check_num_zsq@create_say()def __init__(self,num):self.__result = num@__check_num_zsq@create_say('加')def jia(self,n):self.__result += n@__check_num_zsq@create_say('减去')def jian(self,n):self.__result -= n@__check_num_zsq@create_say('乘以')def cheng(self,n):self.__result *= ndef show(self):# self.__say('计算的结果为:%d' %self.__result)print('计算的结果为:%d' %self.__result)c1 = Caculator(2)c1.jia(6)c1.jian(4)c1.cheng(5)c1.show()
输出结果调用播报器
import win32com.clientclass Caculator:def create_say(word = ''): # 定义一个函数,接收一个参数,函数内部就是一个装饰器,最终将这个装饰器返回def __say_zsq(func): # 装饰器def inner(self,n):speaker = win32com.client.Dispatch("SAPI.SpVoice")speaker.Speak(word + str(n))return func(self,n)return innerreturn __say_zsq # 将函数内部的装饰器返回出去def __check_num_zsq(func):def inner(self,n):if not isinstance(n,int):raise TypeError("当前这个数据有问题,应该为一个数值类型")return func(self,n)return inner@__check_num_zsq@create_say()def __init__(self,num):self.__result = num@__check_num_zsq@create_say('加')def jia(self,n):self.__result += n@__check_num_zsq@create_say('减去')def jian(self,n):self.__result -= n@__check_num_zsq@create_say('乘以')def cheng(self,n):self.__result *= ndef show(self):speaker = win32com.client.Dispatch("SAPI.SpVoice")speaker.Speak('计算的结果为:%d' %self.__result)print('计算的结果为:%d' %self.__result)c1 = Caculator(2)c1.jia(6)c1.jian(4)c1.cheng(5)c1.show()
import win32com.clientclass Caculator:def __check_num_zsq(func):def inner(self,n):if not isinstance(n,int):raise TypeError("当前这个数据有问题,应该为一个数值类型")return func(self,n)return innerdef __say(self,word): # 单独写一个播报器speaker = win32com.client.Dispatch("SAPI.SpVoice")speaker.Speak(word)def __create_say(word = ''): # 定义一个函数,接收一个参数,函数内部就是一个装饰器,最终将这个装饰器返回def __say_zsq(func): # 装饰器def inner(self,n):self.__say(word + str(n))return func(self,n)return innerreturn __say_zsq # 将函数内部的装饰器返回出去@__check_num_zsq@__create_say()def __init__(self,num):self.__result = num@__check_num_zsq@__create_say('加')def jia(self,n):self.__result += n@__check_num_zsq@__create_say('减去')def jian(self,n):self.__result -= n@__check_num_zsq@__create_say('乘以')def cheng(self,n):self.__result *= ndef show(self):self.__say('计算的结果为:%d' %self.__result)print('计算的结果为:%d' %self.__result)c1 = Caculator(2)c1.jia(6)c1.jian(4)c1.cheng(5)c1.show()
在外界使用输出结果(描述器)
import win32com.clientclass Caculator:def __check_num_zsq(func):def inner(self,n):if not isinstance(n,int):raise TypeError("当前这个数据有问题,应该为一个数值类型")return func(self,n)return innerdef __say(self,word):speaker = win32com.client.Dispatch("SAPI.SpVoice")speaker.Speak(word)def __create_say(word = ''): # 定义一个函数,接收一个参数,函数内部就是一个装饰器,最终将这个装饰器返回def __say_zsq(func): # 装饰器def inner(self,n):self.__say(word + str(n))return func(self,n)return innerreturn __say_zsq # 将函数内部的装饰器返回出去@__check_num_zsq@__create_say()def __init__(self,num):self.__result = num@__check_num_zsq@__create_say('加')def jia(self,n):self.__result += n@__check_num_zsq@__create_say('减去')def jian(self,n):self.__result -= n@__check_num_zsq@__create_say('乘以')def cheng(self,n):self.__result *= ndef show(self):self.__say('计算的结果为:%d' %self.__result)print('计算的结果为:%d' %self.__result)@property # 在外界使用输出结果(描述器)def result(self):return self.__resultc1 = Caculator(2)c1.jia(6)c1.jian(4)c1.cheng(5)c1.show()print(c1.result) # 以调用属性的方式调用方法
return self
import win32com.clientclass Caculator:def __check_num_zsq(func):def inner(self,n):if not isinstance(n,int):raise TypeError("当前这个数据有问题,应该为一个数值类型")return func(self,n)return innerdef __say(self,word):speaker = win32com.client.Dispatch("SAPI.SpVoice")speaker.Speak(word)def __create_say(word = ''): # 定义一个函数,接收一个参数,函数内部就是一个装饰器,最终将这个装饰器返回def __say_zsq(func): # 装饰器def inner(self,n):self.__say(word + str(n))return func(self,n)return innerreturn __say_zsq # 将函数内部的装饰器返回出去@__check_num_zsq@__create_say()def __init__(self,num):self.__result = num@__check_num_zsq@__create_say('加')def jia(self,n):self.__result += nreturn self # 返回实例本身@__check_num_zsq@__create_say('减去')def jian(self,n):self.__result -= nreturn self # 返回实例本身@__check_num_zsq@__create_say('乘以')def cheng(self,n):self.__result *= nreturn self # 返回实例本身def show(self):self.__say('计算的结果为:%d' %self.__result)print('计算的结果为:%d' %self.__result)def clear(self):self.__result = 0return self@property # 在外界使用输出结果(描述器)def result(self):return self.__resultc1 = Caculator(2)c1.jia(6).jian(4).cheng(5).jia(20).clear().jia(100) # 链式编程c1.show()print(c1.result) # 以调用属性的方式调用方法
