面向过程的设计思路

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()

  1. <a name="d096e49f"></a>
  2. # 面向对象的设计思路
  3. <a name="2bac1f38"></a>
  4. ## 通过【类属性】来操作运算结果
  5. - 通过类名来访问
  6. ```python
  7. class Caculator:
  8. __result = 0 # 为了不让外界操作这个类属性,即定义一个私有属性
  9. @classmethod
  10. def first_values(cls,v): # 定义类方法,调用类属性,传递一个类名就可以了,这里使用了参数cls
  11. cls.__result = v
  12. @classmethod
  13. def jia(cls,n):
  14. cls.__result += n
  15. @classmethod
  16. def jian(cls,n):
  17. cls.__result -= n
  18. @classmethod
  19. def cheng(cls,n):
  20. cls.__result *= n
  21. @classmethod
  22. def show(cls): # 由于最终要打印计算结果,且结果保存在私有属性中,外界无法访问,所以在内部提供一个方法来访问该私有属性
  23. print('计算的结果为:%d' %cls.__result)
  24. Caculator.first_values(10)
  25. Caculator.jia(5)
  26. Caculator.jian(3)
  27. Caculator.cheng(6)
  28. Caculator.show()

上述代码存在的问题:

  • result是一个类属性,类属性是依赖类对象存在的,在内存中,每个类只会存在一份,所以只能计算一份结果,无法同时进行多个表达式的运算;
  • 另外,当其他多个对象调用这个类属性的时候,调用和修改都是同一个属性的值,所以最终计算得到的结果都是同一个值;

    通过【实例化】来操作运算结果

  • 通过实例化对象来操作计算的结果,就是将result变成一个实例属性,一个实例就是一个计算器,不同的实例就是不同的计算器 ```python class Caculator:

    def init(self,num):

    1. self.__result = num # 初始化,输入计算前第一个数值

    def jia(self,n):

    1. self.__result += n

    def jian(self,n):

    1. self.__result -= n

    def cheng(self,n):

    1. self.__result *= n

    def show(self):

    1. 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()

  1. - 容错处理(对nnum进行判断,是否为整形)
  2. ```python
  3. class Caculator:
  4. def check_num(self,num): # 单独写一个方法,用于判断输入的数值是否为数值型
  5. if not isinstance(num,int):
  6. raise TypeError("当前这个数据有问题,应该为一个数值类型")
  7. def __init__(self,num):
  8. self.check_num(num) # 调用容错处理的方法
  9. self.__result = num
  10. def jia(self,n):
  11. self.check_num(n) # 调用容错处理的方法
  12. self.__result += n
  13. def jian(self,n):
  14. self.check_num(n) # 调用容错处理的方法
  15. self.__result -= n
  16. def cheng(self,n):
  17. self.check_num(n) # 调用容错处理的方法
  18. self.__result *= n
  19. def show(self):
  20. print('计算的结果为:%d' %self.__result)
  21. c1 = Caculator(2)
  22. c1.jia(6)
  23. c1.jian(4)
  24. c1.cheng(5)
  25. c1.show()
  • 上述容错处理的代码中,在方法中又调用了容错处理的方法,破坏了原来的代码的单一原则,原本每个方法只负责加减乘除的操作,现在又增加了额外的功能,即破坏了代码

    容错处理装饰器

    ```python class Caculator: def __check_num_zsq(func): # 重点,定义私有装饰器,避免外界调用或修改

    1. def inner(self,n): # 重点,这里接收的参数和被装饰的方法所接收的参数一致
    2. if not isinstance(n,int):
    3. raise TypeError("当前这个数据有问题,应该为一个数值类型")
    4. return func(self,n) # 执行方法,这里就是执行下面加减乘除的方法
    5. return inner

    @check_num_zsq def init__(self,num):

    1. self.__result = num

    @__check_num_zsq def jia(self,n):

    1. self.__result += n

    @__check_num_zsq def jian(self,n):

    1. self.__result -= n

    @__check_num_zsq def cheng(self,n):

    1. self.__result *= n

    def show(self):

    1. print('计算的结果为:%d' %self.__result)

c1 = Caculator(2) c1.jia(6) c1.jian(4) c1.cheng(5) c1.show()

  1. <a name="23c709c4"></a>
  2. ## 嵌入播报功能
  3. - 如何嵌入
  4. ```python
  5. import win32com.client
  6. class Caculator:
  7. def __say(self,word): # 单独定义一个播报方法,播报的word = n或是num
  8. speaker = win32com.client.Dispatch("SAPI.SpVoice") # 1,创建一个播报器对象
  9. speaker.Speak(word) # 2,通过播报器对象,直接播放相对应的语音字符串
  10. def __check_num_zsq(func): # 重点,定义私有装饰器,避免外界调用或修改
  11. def inner(self,n): # 重点,这里接收的参数和被装饰的方法所接收的参数一致
  12. if not isinstance(n,int):
  13. raise TypeError("当前这个数据有问题,应该为一个数值类型")
  14. return func(self,n) # 执行方法,这里就是执行下面加减乘除的方法
  15. return inner
  16. @__check_num_zsq
  17. def __init__(self,num):
  18. self.__say(num)
  19. self.__result = num
  20. @__check_num_zsq
  21. def jia(self,n):
  22. self.__say(n)
  23. self.__result += n
  24. @__check_num_zsq
  25. def jian(self,n):
  26. self.__say(n)
  27. self.__result -= n
  28. @__check_num_zsq
  29. def cheng(self,n):
  30. self.__say(n)
  31. self.__result *= n
  32. def show(self):
  33. self.__say('计算的结果为:%d' %self.__result)
  34. print('计算的结果为:%d' %self.__result)
  35. c1 = Caculator(2)
  36. c1.jia(6)
  37. c1.jian(4)
  38. c1.cheng(5)
  39. c1.show()

播报装饰器 - 仅播报数字

  1. import win32com.client
  2. class Caculator:
  3. def __say_zsq(func): # 重点,定义私有装饰器,避免外界调用或修改
  4. def inner(self,n):
  5. speaker = win32com.client.Dispatch("SAPI.SpVoice")
  6. speaker.Speak(n)
  7. return func(self,n)
  8. return inner
  9. def __check_num_zsq(func): # 重点,定义私有装饰器,避免外界调用或修改
  10. def inner(self,n): # 重点,这里接收的参数和被装饰的方法所接收的参数一致
  11. if not isinstance(n,int):
  12. raise TypeError("当前这个数据有问题,应该为一个数值类型")
  13. return func(self,n) # 执行方法,这里就是执行下面加减乘除的方法
  14. return inner
  15. @__check_num_zsq
  16. @__say_zsq # 先验证,后播报
  17. def __init__(self,num):
  18. self.__result = num
  19. @__check_num_zsq
  20. @__say_zsq
  21. def jia(self,n):
  22. self.__result += n
  23. @__check_num_zsq
  24. @__say_zsq
  25. def jian(self,n):
  26. self.__result -= n
  27. @__check_num_zsq
  28. @__say_zsq
  29. def cheng(self,n):
  30. self.__result *= n
  31. def show(self):
  32. # self.__say('计算的结果为:%d' %self.__result)
  33. print('计算的结果为:%d' %self.__result)
  34. c1 = Caculator(2)
  35. c1.jia(6)
  36. c1.jian(4)
  37. c1.cheng(5)
  38. c1.show()

带参数的装饰器 - 符号和数字

  1. import win32com.client
  2. class Caculator:
  3. def create_say(word = ''): # 定义一个函数,接收一个参数,函数内部就是一个装饰器,最终将这个装饰器返回
  4. def __say_zsq(func): # 装饰器
  5. def inner(self,n):
  6. speaker = win32com.client.Dispatch("SAPI.SpVoice")
  7. speaker.Speak(word + str(n))
  8. return func(self,n)
  9. return inner
  10. return __say_zsq # 将函数内部的装饰器返回出去
  11. def __check_num_zsq(func):
  12. def inner(self,n):
  13. if not isinstance(n,int):
  14. raise TypeError("当前这个数据有问题,应该为一个数值类型")
  15. return func(self,n)
  16. return inner
  17. @__check_num_zsq
  18. @create_say()
  19. def __init__(self,num):
  20. self.__result = num
  21. @__check_num_zsq
  22. @create_say('加')
  23. def jia(self,n):
  24. self.__result += n
  25. @__check_num_zsq
  26. @create_say('减去')
  27. def jian(self,n):
  28. self.__result -= n
  29. @__check_num_zsq
  30. @create_say('乘以')
  31. def cheng(self,n):
  32. self.__result *= n
  33. def show(self):
  34. # self.__say('计算的结果为:%d' %self.__result)
  35. print('计算的结果为:%d' %self.__result)
  36. c1 = Caculator(2)
  37. c1.jia(6)
  38. c1.jian(4)
  39. c1.cheng(5)
  40. c1.show()

输出结果调用播报器

  1. import win32com.client
  2. class Caculator:
  3. def create_say(word = ''): # 定义一个函数,接收一个参数,函数内部就是一个装饰器,最终将这个装饰器返回
  4. def __say_zsq(func): # 装饰器
  5. def inner(self,n):
  6. speaker = win32com.client.Dispatch("SAPI.SpVoice")
  7. speaker.Speak(word + str(n))
  8. return func(self,n)
  9. return inner
  10. return __say_zsq # 将函数内部的装饰器返回出去
  11. def __check_num_zsq(func):
  12. def inner(self,n):
  13. if not isinstance(n,int):
  14. raise TypeError("当前这个数据有问题,应该为一个数值类型")
  15. return func(self,n)
  16. return inner
  17. @__check_num_zsq
  18. @create_say()
  19. def __init__(self,num):
  20. self.__result = num
  21. @__check_num_zsq
  22. @create_say('加')
  23. def jia(self,n):
  24. self.__result += n
  25. @__check_num_zsq
  26. @create_say('减去')
  27. def jian(self,n):
  28. self.__result -= n
  29. @__check_num_zsq
  30. @create_say('乘以')
  31. def cheng(self,n):
  32. self.__result *= n
  33. def show(self):
  34. speaker = win32com.client.Dispatch("SAPI.SpVoice")
  35. speaker.Speak('计算的结果为:%d' %self.__result)
  36. print('计算的结果为:%d' %self.__result)
  37. c1 = Caculator(2)
  38. c1.jia(6)
  39. c1.jian(4)
  40. c1.cheng(5)
  41. c1.show()
  1. import win32com.client
  2. class Caculator:
  3. def __check_num_zsq(func):
  4. def inner(self,n):
  5. if not isinstance(n,int):
  6. raise TypeError("当前这个数据有问题,应该为一个数值类型")
  7. return func(self,n)
  8. return inner
  9. def __say(self,word): # 单独写一个播报器
  10. speaker = win32com.client.Dispatch("SAPI.SpVoice")
  11. speaker.Speak(word)
  12. def __create_say(word = ''): # 定义一个函数,接收一个参数,函数内部就是一个装饰器,最终将这个装饰器返回
  13. def __say_zsq(func): # 装饰器
  14. def inner(self,n):
  15. self.__say(word + str(n))
  16. return func(self,n)
  17. return inner
  18. return __say_zsq # 将函数内部的装饰器返回出去
  19. @__check_num_zsq
  20. @__create_say()
  21. def __init__(self,num):
  22. self.__result = num
  23. @__check_num_zsq
  24. @__create_say('加')
  25. def jia(self,n):
  26. self.__result += n
  27. @__check_num_zsq
  28. @__create_say('减去')
  29. def jian(self,n):
  30. self.__result -= n
  31. @__check_num_zsq
  32. @__create_say('乘以')
  33. def cheng(self,n):
  34. self.__result *= n
  35. def show(self):
  36. self.__say('计算的结果为:%d' %self.__result)
  37. print('计算的结果为:%d' %self.__result)
  38. c1 = Caculator(2)
  39. c1.jia(6)
  40. c1.jian(4)
  41. c1.cheng(5)
  42. c1.show()

在外界使用输出结果(描述器)

  1. import win32com.client
  2. class Caculator:
  3. def __check_num_zsq(func):
  4. def inner(self,n):
  5. if not isinstance(n,int):
  6. raise TypeError("当前这个数据有问题,应该为一个数值类型")
  7. return func(self,n)
  8. return inner
  9. def __say(self,word):
  10. speaker = win32com.client.Dispatch("SAPI.SpVoice")
  11. speaker.Speak(word)
  12. def __create_say(word = ''): # 定义一个函数,接收一个参数,函数内部就是一个装饰器,最终将这个装饰器返回
  13. def __say_zsq(func): # 装饰器
  14. def inner(self,n):
  15. self.__say(word + str(n))
  16. return func(self,n)
  17. return inner
  18. return __say_zsq # 将函数内部的装饰器返回出去
  19. @__check_num_zsq
  20. @__create_say()
  21. def __init__(self,num):
  22. self.__result = num
  23. @__check_num_zsq
  24. @__create_say('加')
  25. def jia(self,n):
  26. self.__result += n
  27. @__check_num_zsq
  28. @__create_say('减去')
  29. def jian(self,n):
  30. self.__result -= n
  31. @__check_num_zsq
  32. @__create_say('乘以')
  33. def cheng(self,n):
  34. self.__result *= n
  35. def show(self):
  36. self.__say('计算的结果为:%d' %self.__result)
  37. print('计算的结果为:%d' %self.__result)
  38. @property # 在外界使用输出结果(描述器)
  39. def result(self):
  40. return self.__result
  41. c1 = Caculator(2)
  42. c1.jia(6)
  43. c1.jian(4)
  44. c1.cheng(5)
  45. c1.show()
  46. print(c1.result) # 以调用属性的方式调用方法

return self

  1. import win32com.client
  2. class Caculator:
  3. def __check_num_zsq(func):
  4. def inner(self,n):
  5. if not isinstance(n,int):
  6. raise TypeError("当前这个数据有问题,应该为一个数值类型")
  7. return func(self,n)
  8. return inner
  9. def __say(self,word):
  10. speaker = win32com.client.Dispatch("SAPI.SpVoice")
  11. speaker.Speak(word)
  12. def __create_say(word = ''): # 定义一个函数,接收一个参数,函数内部就是一个装饰器,最终将这个装饰器返回
  13. def __say_zsq(func): # 装饰器
  14. def inner(self,n):
  15. self.__say(word + str(n))
  16. return func(self,n)
  17. return inner
  18. return __say_zsq # 将函数内部的装饰器返回出去
  19. @__check_num_zsq
  20. @__create_say()
  21. def __init__(self,num):
  22. self.__result = num
  23. @__check_num_zsq
  24. @__create_say('加')
  25. def jia(self,n):
  26. self.__result += n
  27. return self # 返回实例本身
  28. @__check_num_zsq
  29. @__create_say('减去')
  30. def jian(self,n):
  31. self.__result -= n
  32. return self # 返回实例本身
  33. @__check_num_zsq
  34. @__create_say('乘以')
  35. def cheng(self,n):
  36. self.__result *= n
  37. return self # 返回实例本身
  38. def show(self):
  39. self.__say('计算的结果为:%d' %self.__result)
  40. print('计算的结果为:%d' %self.__result)
  41. def clear(self):
  42. self.__result = 0
  43. return self
  44. @property # 在外界使用输出结果(描述器)
  45. def result(self):
  46. return self.__result
  47. c1 = Caculator(2)
  48. c1.jia(6).jian(4).cheng(5).jia(20).clear().jia(100) # 链式编程
  49. c1.show()
  50. print(c1.result) # 以调用属性的方式调用方法