1 目标:通过计算器, 实现一些基本的操作, 如加减乘除运算, 以及打印结果等。
- 需求:(2 + 6 - 4) * 5
2 实现
从上往下是思想及面向对象技巧使用演变
2.1 普通面向过程思想1
def jia(n1, n2):
return n1 + n2
def jian(n1, n2):
return n1 - n2
def cheng(n1, n2):
return n1 * n2
r1 = jia(2, 6)
r2 = jian(r1, 4)
r3 = cheng(r2, 5)
print(r3)
>>>> 打印结果
20
2.2 普通面向过程思想2
- 函数内部对全局变量的修改(通过
global
语句修饰) - 通过函数输入初始值
- 全局变量容易被修改
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
first_value(2)
jia(6)
# result = 123# 易被修改全局变量
jian(4)
cheng(5)
print(result)
>>>> 打印结果
20
2.3 面向对象思想1
- 面向对象
- 实例化类对象
- 类方法声明实现,第一参数默认值
- 类对象私有属性
class Caculator:
__result = 0
@classmethod
def first_value(cls, v):
cls.__result = v
@classmethod
def jia(cls, n):
cls.__result += n
@classmethod
def jian(cls, n):
cls.__result -= n
@classmethod
def cheng(cls, n):
cls.__result *= n
@classmethod
def show(cls):
print("计算的结果是:%d" % cls.__result)
Caculator.first_value(2)
Caculator.jia(6)
Caculator.jian(4)
Caculator.cheng(5)
Caculator.show()
>>>> 打印结果
计算的结果是:20
2.4 面向对象思想2
- 重写类对象实例初始化方法,创建对象时给实例传入实例属性
- 因,类私有属性具有公用性,应,采用实例私有属性
- 实例方法声明实现,第一参数默认值
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(2)
c1.jia(6)
c1.jian(4)
c1.cheng(5)
c1.show()
>>>> 打印结果
计算的结果是:20
2.5 面向对象思想3
- 通过实例方法对原有方法扩展
- 抛异常,代码健壮性检测
class Caculator:
def check_num(self, num):
if not isinstance(num, int):
raise TypeError("当前这个数据的类型有问题, 应该是一个整型数据")
def __init__(self, num):
self.check_num(num)
self.__result = num
def jia(self, n):
self.check_num(n)
self.__result += n
def jian(self, n):
self.check_num(n)
self.__result -= n
def cheng(self, n):
self.check_num(n)
self.__result *= n
def show(self):
print("计算的结果是:%d" % self.__result)
c1 = Caculator(2)
c1.jia(6)
c1.jian("a") #输入不合理参数
c1.cheng(5)
c1.show()
>>>> 打印结果
Traceback (most recent call last):
File "/Users/xxx/Desktop/PythonProject/AreaDefine/面向对象案例.py", line 157, in
c1.jian("a")
File "/Users/xxx/Desktop/PythonProject/AreaDefine/面向对象案例.py", line 144, in jian
self.check_num(n)
File "/Users/xxx/Desktop/PythonProject/AreaDefine/面向对象案例.py", line 133, in check_num
raise TypeError("当前这个数据的类型有问题, 应该是一个整型数据")
TypeError: 当前这个数据的类型有问题, 应该是一个整型数据
2.6 面向对象思想4
- 函数装饰器定义及使用
- 通过函数装饰器扩展原有方法
- 所有方法都可以被装饰器扩展(如
__init__
)
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()
>>>> 打印结果
计算的结果是:20
。。。接上述代码之后
# 因为装饰函数并未私有化,所以外界可以调用
def test(n):
print(n)
c1.check_num_zsq(test)
>>>> 打印结果
计算的结果是:20
Traceback (most recent call last):
File "/Users/xxx/Desktop/PythonProject/AreaDefine/面向对象案例.py", line 202, in
c1.check_num_zsq(test)
TypeError: check_num_zsq() takes 1 positional argument but 2 were given
2.7 面向对象思想5
- 私有化函数装饰器,防止外界调用
- @后的装饰器函数名需一样
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()
>>>> 打印结果
计算的结果是:20
2.8 面向对象思想6
- Windows 、Mac的语音播报模块使用
- 装饰器的叠加,执行顺序(从上到下执行)
- 装饰器的生成(按传参生成不同装饰器)
- 方法传参默认值,有默认值可以不用传参数
# import win32com.client
import os
# test
# # window 下的播报实现
# # 1. 创建一个播报器对象
# speaker = win32com.client.Dispatch("SAPI.SpVoice")
# # 2. 通过这个播报器对象, 直接, 播放相对应的语音字符串就可以
# speaker.Speak("我的名字是FKM")
# Mac 下的播报实现
# os.system("say '" + "我的名字是FKM" + "' ")
class Caculator:
def __check_num_zsq(func):
def inner(self, n):
if not isinstance(n, int):
raise TypeError("当前这个数据的类型有问题, 应该是一个整型数据")
return func(self, n)
return inner
def __say(self, word):
# # Windows
# speaker = win32com.client.Dispatch("SAPI.SpVoice")
# speaker.Speak(word)
# Mac
os.system("say '" + word + "' ")
def create_say_zsq(word=""):
def __say_zsq(func):
def inner(self, n):
# # Windows
# speaker = win32com.client.Dispatch("SAPI.SpVoice")
# speaker.Speak(word + str(n))
# Mac
os.system("say '" + word + str(n) + "' ")
return func(self, n)
return inner
return __say_zsq
@__check_num_zsq
@create_say_zsq()
def __init__(self, num):
self.__result = num
@__check_num_zsq
@create_say_zsq("加")
def jia(self, n):
self.__result += n
@__check_num_zsq
@create_say_zsq("减去")
def jian(self, n):
self.__result -= n
@__check_num_zsq
@create_say_zsq("乘以")
def cheng(self, n):
self.__result *= n
def show(self):
self.__say("计算的结果是:%d" % self.__result)
print("计算的结果是:%d" % self.__result)
c1 = Caculator(10)
c1.jia(6)
c1.jian(4)
c1.cheng(5)
c1.show()
>>>> 打印结果
计算的结果是:60
2.9 面向对象思想7
- 整合 __say 和 __say_zsq 内的多分播报代码,方便以后只修改一处即可
# import win32com.client
import os
# test
# # window 下的播报实现
# # 1. 创建一个播报器对象
# speaker = win32com.client.Dispatch("SAPI.SpVoice")
# # 2. 通过这个播报器对象, 直接, 播放相对应的语音字符串就可以
# speaker.Speak("我的名字是FKM")
# Mac 下的播报实现
# os.system("say '" + "我的名字是FKM" + "' ")
class Caculator:
def __check_num_zsq(func):
def inner(self, n):
if not isinstance(n, int):
raise TypeError("当前这个数据的类型有问题, 应该是一个整型数据")
return func(self, n)
return inner
def __say(self, word):
# # Windows
# speaker = win32com.client.Dispatch("SAPI.SpVoice")
# speaker.Speak(word)
# Mac
os.system("say '" + word + "' ")
def create_say_zsq(word=""):
def __say_zsq(func):
def inner(self, n):
self.__say(word + str(n)) # 整合位置
return func(self, n)
return inner
return __say_zsq
@__check_num_zsq
@create_say_zsq()
def __init__(self, num):
self.__result = num
@__check_num_zsq
@create_say_zsq("加")
def jia(self, n):
self.__result += n
@__check_num_zsq
@create_say_zsq("减去")
def jian(self, n):
self.__result -= n
@__check_num_zsq
@create_say_zsq("乘以")
def cheng(self, n):
self.__result *= n
def show(self):
self.__say("计算的结果是:%d" % self.__result)
print("计算的结果是:%d" % self.__result)
c1 = Caculator(10)
c1.jia(6)
c1.jian(4)
c1.cheng(5)
c1.show()
>>>> 打印结果
计算的结果是:60
2.10 面向对象思想8
- 通过@property让外界通过点语法,获取实例私有属性值
# import win32com.client
import os
# test
# # window 下的播报实现
# # 1. 创建一个播报器对象
# speaker = win32com.client.Dispatch("SAPI.SpVoice")
# # 2. 通过这个播报器对象, 直接, 播放相对应的语音字符串就可以
# speaker.Speak("我的名字是FKM")
# Mac 下的播报实现
# os.system("say '" + "我的名字是FKM" + "' ")
class Caculator:
def __check_num_zsq(func):
def inner(self, n):
if not isinstance(n, int):
raise TypeError("当前这个数据的类型有问题, 应该是一个整型数据")
return func(self, n)
return inner
def __say(self, word):
# # Windows
# speaker = win32com.client.Dispatch("SAPI.SpVoice")
# speaker.Speak(word)
# Mac
os.system("say '" + word + "' ")
def create_say_zsq(word=""):
def __say_zsq(func):
def inner(self, n):
# # Windows
# speaker = win32com.client.Dispatch("SAPI.SpVoice")
# speaker.Speak(word + str(n))
# Mac
os.system("say '" + word + str(n) + "' ")
return func(self, n)
return inner
return __say_zsq
@__check_num_zsq
@create_say_zsq()
def __init__(self, num):
self.__result = num
@__check_num_zsq
@create_say_zsq("加")
def jia(self, n):
self.__result += n
@__check_num_zsq
@create_say_zsq("减去")
def jian(self, n):
self.__result -= n
@__check_num_zsq
@create_say_zsq("乘以")
def cheng(self, n):
self.__result *= n
def show(self):
self.__say("计算的结果是:%d" % self.__result)
print("计算的结果是:%d" % self.__result)
@property
def result(self):
return self.__result
c1 = Caculator(10)
c1.jia(6)
c1.jian(4)
c1.cheng(5)
c1.show()
print(c1.result)
# c1.result = 10 # 外界不能修改
>>>> 打印结果
计算的结果是:60
60
2.11 面向对象思想9
- 链式编程思想:通过实例方法返回实例达到链式调用条件
# import win32com.client
import os
class Caculator:
def __check_num_zsq(func):
def inner(self, n):
if not isinstance(n, int):
raise TypeError("当前这个数据的类型有问题, 应该是一个整型数据")
return func(self, n)
return inner
def __say(self, word):
# window 下的播报实现
# 1. 创建一个播报器对象
# speaker = win32com.client.Dispatch("SAPI.SpVoice")
#
# # 2. 通过这个播报器对象, 直接, 播放相对应的语音字符串就可以
# speaker.Speak(word)
# Mac 下的播报实现
os.system("say '" + word + "' ")
def __create_say_zsq(word=""):
def __say_zsq(func):
def inner(self, n):
self.__say(word + str(n))
return func(self, n)
return inner
return __say_zsq
@__check_num_zsq
@__create_say_zsq()
def __init__(self, num):
self.__result = num
@__check_num_zsq
@__create_say_zsq("加")
def jia(self, n):
self.__result += n
return self
@__check_num_zsq
@__create_say_zsq("减去")
def jian(self, n):
self.__result -= n
return self
@__check_num_zsq
@__create_say_zsq("乘以")
def cheng(self, n):
self.__result *= n
return self
def show(self):
self.__say("计算的结果是:%d" % self.__result)
print("计算的结果是:%d" % self.__result)
return self
def clear(self):
self.__result = 0
return self
@property
def result(self):
return self.__result
c1 = Caculator(10)
c1.jia(6).jian(4).cheng(5).show().clear().jia(555).jian(500).show()
print(c1.result)
>>>> 打印结果
计算的结果是:60
计算的结果是:55
55