面向对象object-oriented

"""面向对象思考流程:现实世界             软件世界客观事物              app(滴滴打车)汽车 --抽象化--> 类 --具体化--> 对象品牌            奔驰车牌            007颜色            白色...
"""

定义类

class 类名:"""文档说明"""def __init__(self,参数):self.实例变量 = 参数方法(函数)成员说明:   类名所有单词首字母大写。init 也叫构造函数,创建对象时被调用,也可以省略。self变量绑定的是被创建的对象,名称可以随意,但不会改,行业默认。

实例化对象

变量 = 类名(参数)   #即创建对象(自动调用__init__)
变量存储的是实例化后的对象地址,类名后面的参数按照构造函数的形参传递

举例

alt+enter 弹出创建参数,自动补充def后面的参数

class Wife:# 数据def __init__(self, name, age=18, face_score=60):self.name = nameself.age = age  # (输入完,alt+enter 弹出创建参数age,自动补充def后面的参数)self.face_score =face_score# ....# 行为-方法函数def work(self):print(self.name + "working")# 实例化
# 创建对象(自动调用__init__)
shuang_er = Wife("双儿", 23, 93)# 读取对象数据
print(shuang_er.name)  #输出 双儿# 调用对象方法
shuang_er.work() # 输出 双儿working#创建新的对象
jian_ning = Wife("建宁")
# 修改对象数据
print(jian_ning.face_score)    #60
jian_ning.face_score = 95
print(jian_ning.face_score)   #90

"""练习:创建手机类,实例化两个对象并调用其函数,数据:品牌、价格、颜色行为:通话
"""# 类明:所有单词首字母大写,不用下划线分割
class MobilePhone:def __init__(self, brand, price=0, color=""):self.brand = brandself.price = priceself.color = color  # alt + 回车def call(self):print(self.brand, "在通话")huawei = MobilePhone("华为", 8000, "白色")
iphone = MobilePhone("苹果", color =  "黑色")print(huawei.price)    #8000
huawei.call()    #华为 在通话
iphone.call()    #华为 在通话

实例成员: 实例变量、实例方法

"""实例成员实例变量:表达不同个体的不同数据语法:对象.变量名实例方法:操作实例变量语法:def 方法名(self,参数):方法体对象.方法名(数据)
"""class Wife:def __init__(self, name=""):# 创建实例变量self.name = name# 实例方法def work(self):print(self.name + "在工作")#创建
shuang_er = Wife("双儿")# 修改实例变量
shuang_er.name = "双双"# 读取实例变量
print(shuang_er.name)# __dict__ 存储所有实例变量
print(shuang_er.__dict__)  # {'name': '双双'}# 通过对象访问实例方法
shuang_er.work()  # work(shuang_er)

不建议在类外创建实例变量

# 不建议在类外创建实例变量
class Wife:passshuang_er = Wife()
# 创建实例变量
shuang_er.name = "双双"
# 读取实例变量
print(shuang_er.name)
# __dict__ 存储所有实例变量
print(shuang_er.__dict__)  # {'name': '双双'}

不建议在__init__外创建实例变量

# 不建议在__init__外创建实例变量
class Wife:def set_name(self, name):# 创建实例变量self.name = nameshuang_er = Wife()
shuang_er.set_name("双双")
print(shuang_er.name)
print(shuang_er.__dict__)

练习

"""创建狗类数据:品种、昵称、身长、体重行为:吃(体重增长1)实例化两个对象并调用其函数
"""class Dog:def __init__(self, species="", pet_name="", height=0.0, weight=0):self.species = speciesself.pet_name = pet_nameself.height = heightself.weight = weightself.eat()def eat(self):self.weight += 1print("吃饭饭~")    #不创建对象是不会打印,创建时会打印一次,mi_xiu = Dog("拉布拉多", "米咻", 0.6, 60)   #打印出 吃饭饭~
print(mi_xiu.weight)    # 61
mi_xiu.eat()  # eat(mi_xiu)    #使用时打印  吃饭饭~
print(mi_xiu.weight)  #61

练习

class Wife:def __init__(self, name, age=20):self.name = nameself.age = age# 练习1:
person01 = Wife("双儿", 23)  #创建了内存地址
person02 = person01   #给person02赋值了内存地址
person01.name = "双双"
print(person02.name)  # 打印出双双# 练习2:
def func01(p1, p2):p1.name = "双双"p2 = Wife("宁宁", 26)person01 = Wife("双儿", 23)
person02 = Wife("建宁", 25)
func01(person01, person02)  #p1产生修改   p2在栈帧内指向新地址("宁宁", 26),栈帧执行完销毁
print(person01.name)  # 双双
print(person02.name)  # 建宁
# 练习3:
person01 = Wife("双儿", 23)
list_wifes = [person01,Wife("建宁", 25),Wife("阿珂", 22),
]def func01(p1):p1[0].name = "双双"p1[1] = Wife("宁宁", 25)p1[2] = "珂珂"func01(list_wifes)
print(list_wifes[0].name)  #双双
print(list_wifes[1].name)  #宁宁
print(list_wifes[2])    #珂珂,整个p1[2]被修改成珂珂(就没.mame可调用打印了)

"""定义函数,在老婆列表中查找,姓名是阿珂的老婆.定义函数,在老婆列表中查找,年龄大于25岁的所有老婆.定义函数,在老婆列表中查找,查找颜值小于95的所有老婆姓名.定义函数,累加所有老婆的年龄定义函数,在老婆列表中查找,年龄最大的老婆定义函数,根据颜值对老婆列表生序排列
"""# -------------类----------------
class Wife:def __init__(self, name, age=20, face_score=60):self.name = nameself.age = ageself.face_score = face_score# -------------全局变量----------------list_wifes = [Wife("双儿", 23, 93),Wife("建宁", 26, 91),Wife("阿珂", 22, 100),Wife("苏荃", 32, 92),
]# -------------函数----------------# 定义函数,在老婆列表中查找,姓名是阿珂的老婆.
def find_single_wife_by_name():for item in list_wifes:if item.name == "阿珂":return item# 定义函数,在老婆列表中查找,年龄大于25岁的所有老婆.
def find_all_wife_by_age():list_result = []for item in list_wifes:if item.age > 25:list_result.append(item)return list_result# 定义函数,在老婆列表中查找,查找颜值小于95的所有老婆姓名.
def find_all_name_by_face_score():list_result = []for item in list_wifes:if item.face_score < 95:list_result.append(item.name)return list_result# 定义函数,累加所有老婆的年龄
def sum_age():result = 0for item in list_wifes:result += item.agereturn result# 定义函数,在老婆列表中查找,年龄最大的老婆
def get_max_by_age():max_value = list_wifes[0]for i in range(1, len(list_wifes)):if max_value.age < list_wifes[i].age:max_value = list_wifes[i]return max_value# 定义函数,根据颜值对老婆列表生序排列
def order_by_face_score():for r in range(len(list_wifes) - 1):for c in range(r + 1, len(list_wifes)):if list_wifes[r].face_score > list_wifes[c].face_score:list_wifes[r], list_wifes[c] = list_wifes[c], list_wifes[r]# -------------调用----------------a_ke = find_single_wife_by_name()
# 建议通过__dict__查看自定义对象的数据
print(a_ke)  #<__main__.Wife object at 0x000001B5355B4EE0>,这个是内存地址。__dict__完成实例对象变量调用
print(a_ke.__dict__)    #{'name': '阿珂', 'age': 22, 'face_score': 100}list_result = find_all_wife_by_age()
# 建议通过断点查看自定义对象的列表
print(list_result)  #[<__main__.Wife object at 0x000001D891474F70>, <__main__.Wife object at 0x000001D891474E20>]
# for item in list_result:
#     print(item.__dict__)    #{'name': '建宁', 'age': 26, 'face_score': 91}#{'name': '苏荃', 'age': 32, 'face_score': 92}list_names = find_all_name_by_face_score()
print(list_names)   #['双儿', '建宁', '苏荃']total_age = sum_age()
print(total_age)   #103value = get_max_by_age()
print(value.__dict__)  #{'name': '苏荃', 'age': 32, 'face_score': 92}order_by_face_score()
print(list_wifes)  #[<__main__.Wife object at 0x000001BF22D24F70>, <__main__.Wife object at 0x000001BF22D24E20>, <__main__.Wife object at 0x000001BF22D24FD0>, <__main__.Wife object at 0x000001BF22D24EE0>]

面向过程->面向对象

"""面向过程->面向对象    抽象化过程
list_commodity_infos = [{"cid": 1001, "name": "屠龙刀", "price": 10000},{"cid": 1002, "name": "倚天剑", "price": 10000},{"cid": 1003, "name": "金箍棒", "price": 52100},{"cid": 1004, "name": "口罩", "price": 20},{"cid": 1005, "name": "酒精", "price": 30},
]
"""class Commodity:def __init__(self, cid=0, name="", price=0):self.cid = cidself.name = nameself.price = pricelist_commodity_infos = [Commodity(1001, "屠龙刀", 10000),Commodity(1002, "倚天剑", 10000),Commodity(1003, "金箍棒", 52100),Commodity(1004, "口罩", 20),Commodity(1005, "酒精", 30),
]def print_single_commodity(commodity):print(f"编号:{commodity.cid},商品名称:{commodity.name},商品单价:{commodity.price}")print_single_commodity(list_commodity_infos[0]) #编号:1001,商品名称:屠龙刀,商品单价:10000
print_single_commodity(list_commodity_infos[1]) #编号:1002,商品名称:倚天剑,商品单价:10000

将面向过程代码改为面向对象代码

"""
#商品列表
list_commodity_infos = [{"cid": 1001, "name": "屠龙刀", "price": 10000},{"cid": 1002, "name": "倚天剑", "price": 10000},{"cid": 1003, "name": "金箍棒", "price": 52100},{"cid": 1004, "name": "口罩", "price": 20},{"cid": 1005, "name": "酒精", "price": 30},
]# 订单列表
list_orders = [{"cid": 1001, "count": 1},{"cid": 1002, "count": 3},{"cid": 1005, "count": 2},
]def print_single_commodity(commodity):print(f"编号:{commodity['cid']},商品名称:{commodity['name']},商品单价:{commodity['price']}")# 1. 定义函数,打印所有商品信息,格式:商品编号xx,商品名称xx,商品单价xx.
def print_commodity_infos():for commodity in list_commodity_infos:print_single_commodity(commodity)# 2. 定义函数,打印商品单价小于2万的商品信息
def print_price_in_2w():for commodity in list_commodity_infos:if commodity["price"] < 20000:print_single_commodity(commodity)# 3. 定义函数,打印所有订单中的商品信息,
def print_order_infos():for order in list_orders:for commodity in list_commodity_infos:if order["cid"] == commodity["cid"]:print(f"商品名称{commodity['name']},商品单价:{commodity['price']},数量{order['count']}.")break # 跳出内层循环# 4. 查找最贵的商品(使用自定义算法,不使用内置函数)
def commodity_max_by_price():max_value = list_commodity_infos[0]for i in range(1, len(list_commodity_infos)):if max_value["price"] < list_commodity_infos[i]["price"]:max_value = list_commodity_infos[i]return max_value# 5. 根据单价对商品列表降序排列
def descending_order_by_price():for r in range(len(list_commodity_infos) - 1):for c in range(r + 1, len(list_commodity_infos)):if list_commodity_infos[r]["price"] < list_commodity_infos[c]["price"]:list_commodity_infos[r], list_commodity_infos[c] = list_commodity_infos[c], list_commodity_infos[r]
"""class Commodity:def __init__(self, cid, name, price):self.cid = cidself.name = nameself.price = priceclass Order:def __init__(self, cid, count):self.cid = cidself.count = countlist_commodity_infos = [Commodity(1001, "屠龙刀", 10000),Commodity(1002, "倚天剑", 10000),Commodity(1003, "金箍棒", 52100),Commodity(1004, "口罩", 20),Commodity(1005, "酒精", 30),
]list_orders = [Order(1001, 1),Order(1002, 3),Order(1005, 2),
]def print_single_commodity(commodity):print(f"编号:{commodity.cid},商品名称:{commodity.name},商品单价:{commodity.price}")# 1. 定义函数,打印所有商品信息,格式:商品编号xx,商品名称xx,商品单价xx.
def print_commodity_infos():for commodity in list_commodity_infos:print_single_commodity(commodity)def print_price_in_2w():for commodity in list_commodity_infos:if commodity.price < 20000:print_single_commodity(commodity)# 3. 定义函数,打印所有订单中的商品信息,
def print_order_infos():for order in list_orders:for commodity in list_commodity_infos:if order.cid == commodity.cid:print(f"商品名称{commodity.name},商品单价:{commodity.price},数量{order.count}.")break# 4. 查找最贵的商品(使用自定义算法,不使用内置函数)
def commodity_max_by_price():max_value = list_commodity_infos[0]for i in range(1, len(list_commodity_infos)):if max_value.price < list_commodity_infos[i].price:max_value = list_commodity_infos[i]return max_value# 5. 根据单价对商品列表降序排列
def descending_order_by_price():for r in range(len(list_commodity_infos) - 1):for c in range(r + 1, len(list_commodity_infos)):if list_commodity_infos[r].price < list_commodity_infos[c].price:list_commodity_infos[r], list_commodity_infos[c] = list_commodity_infos[c], list_commodity_infos[r]# -------------调用----------------
print_commodity_infos()
print_price_in_2w()
print_order_infos()cmd = commodity_max_by_price()
print(cmd.__dict__)descending_order_by_price()
print(list_commodity_infos)

跨类调用

"""跨类调用为什么创建类?因为类需要包装多个数据,承担相应行为.如何跨类调用?直接创建对象,构造函数中创建对象,参数传递对象
"""
# 需求:请使用面向对象思想,描述下列情景.
#  -- 老张开车去东北,抽象成Person人物去哪,Car方式
class Person:def __init__(self, name=""):self.name = namedef go_to(self, position):print("去" + position)class Car:def run(self):print("汽车在行驶")

直接创建对象

# 语义:老张每次去东北,都开一辆新车(每次都会创建车).
class Person:def __init__(self, name=""):self.name = namedef go_to(self, position):print("去" + position)car = Car()    #直接调用下面的Car类,创建对象car.run()class Car:def run(self):print("汽车在行驶")zl = Person("老张")
zl.go_to("东北")    #去东北\n汽车在行驶

在构造函数中创建对象

# 语义:老张去东北,开自己的车(随老张的构建产生)
class Person:def __init__(self, name=""):self.name = nameself.car = Car()  #随老张的构建产生,不会在每次go_to的时候创建新的def go_to(self, position):print("去" + position)self.car.run()class Car:def run(self):print("汽车在行驶")zl = Person("老张")
zl.go_to("东北")

通过参数传递对象(使用较多)

# 语义: 老张通过交通工具(传参vehicle)去东北
class Person:def __init__(self, name=""):self.name = namedef go_to(self, position, vehicle):print("去" + position)vehicle.run()class Car:def run(self):print("汽车在行驶")# 在使用时创建,传递参数
zl = Person("老张")
car = Car()   #创建car对象
zl.go_to("东北", car)    #传递参数进去
"""练习1:以面向对象思想,描述下列情景.小明请保洁打扫卫生
"""
# 语义:小明每次通知新保洁员打扫卫生
"""
class Client:def __init__(self, name=""):self.name = namedef notify(self):print("发出通知")cleaner = Cleaner()cleaner.cleaning()class Cleaner:def cleaning(self):print("打扫卫生")xm = Client("小明")
xm.notify()
"""# 语义:小明每次通知自己的保洁员打扫卫生
"""
class Client:def __init__(self, name=""):self.name = name self.cleaner = Cleaner()def notify(self):print("发出通知") self.cleaner.cleaning()class Cleaner:def cleaning(self):print("打扫卫生")xm = Client("小明")
xm.notify()
"""# 语义:小明每次通知自己的保洁员打扫卫生
class Client:def __init__(self, name=""):self.name = namedef notify(self, server):print("发出通知")server.cleaning()class Cleaner:def cleaning(self):print("打扫卫生")xm = Client("小明")
cleaner = Cleaner()
xm.notify(cleaner)

练习

""" 1. 定义函数,打印所有员工信息,格式:xx的员工编号是xx,部门编号是xx,月薪xx元.2. 定义函数,打印所有月薪大于2w的员工信息,格式:xx的员工编号是xx,部门编号是xx,月薪xx元.3. 定义函数,打印所有员工的部门信息,格式:xx的部门是xx,月薪xx元.4. 定义函数,查找薪资最少的员工5. 定义函数,根据薪资对员工列表升序排列*6.定义函数,计算所有员工总薪资*7.定义函数,获取所有员工姓名结果:["师父","孙悟空","猪八戒","沙僧","小白龙"]# 员工列表list_employees = [{"eid": 1001, "did": 9002, "name": "师父", "money": 60000},{"eid": 1002, "did": 9001, "name": "孙悟空", "money": 50000},{"eid": 1003, "did": 9002, "name": "猪八戒", "money": 20000},{"eid": 1004, "did": 9001, "name": "沙僧", "money": 30000},{"eid": 1005, "did": 9001, "name": "小白龙", "money": 15000},]# 部门列表list_departments = [{"did": 9001, "title": "教学部"},{"did": 9002, "title": "销售部"},]
"""# -------------类--------------
class Employee:def __init__(self, eid, did, name, money):self.eid = eidself.did = didself.name = nameself.money = moneyclass Department:def __init__(self, did, title):self.did = didself.title = title# -------------全局变量--------------# 员工列表
list_employees = [Employee(1001, 9002, "师父", 60000),Employee(1002, 9001, "孙悟空", 50000),Employee(1003, 9002, "猪八戒", 20000),Employee(1004, 9001, "沙僧", 30000),Employee(1005, 9001, "小白龙", 15000),
]# 部门列表
list_departments = [Department(9001, "教学部"),Department(9002, "销售部")
]# -------------函数--------------
# 1. 定义函数,打印所有员工信息,格式:xx的员工编号是xx,部门编号是xx,月薪xx元.
def print_employee_info(emp):print(f"{emp.name}的员工编号是{emp.eid},部门编号是{emp.did},月薪{emp.money}元.")def print_employee_infos():for emp in list_employees:print_employee_info(emp)# 2. 定义函数,打印所有月薪大于2w的员工信息,格式:xx的员工编号是xx,部门编号是xx,月薪xx元.
def print_employees_gt_2w():for emp in list_employees:if emp.money > 20000:print_employee_info(emp)# 3. 定义函数,打印所有员工的部门信息,格式:xx的部门是xx,月薪xx元.
def print_employees_for_department():# 取员工for emp in list_employees:# 找部门for dep in list_departments:if emp.did == dep.did:print(f"{emp.name}的部门是{dep.title},月薪{emp.money}元.")break# 4. 查找薪资最少的员工
def employee_min_by_money():min_value = list_employees[0]for i in range(1, len(list_employees)):if min_value.money > list_employees[i].money:min_value = list_employees[i]return min_value# 5. 根据薪资对员工列表降序排列
def ascending_employee_by_money():for r in range(len(list_employees) - 1):for c in range(r + 1, len(list_employees)):if list_employees[r].money < list_employees[c].money:list_employees[r], list_employees[c] = list_employees[c], list_employees[r]# 6.定义函数, 计算所有员工总薪资
def calculate_total_money():total_money = 0for item in list_employees:total_money += item.moneyreturn total_money# 7.定义函数,获取所有员工姓名
def get_all_name():list_name = []for item in list_employees:list_name.append(item.name)return list_name# -------------入口--------------
result01 = get_all_name()
# 返回的是Python自带类型,可以直接打印
print(result01)  #['师父', '孙悟空', '猪八戒', '沙僧', '小白龙']result02 = calculate_total_money()
print(result02)   #175000ascending_employee_by_money()
print(list_employees)   #返回地址result04 = employee_min_by_money()
# 返回的是自定义类型,打印 __dict__
print(result04.__dict__)   #{'eid': 1005, 'did': 9001, 'name': '小白龙', 'money': 15000}# 内部直接显示结果,无需接收返回值
print_employees_for_department()  #师父的部门是销售部,月薪60000元.孙悟空的...

复习-跨类调用

    1. 为什么创建类?有多个数据需要包装有行为需要承担2. 为什么创建多个类?根据变化点,分担多个职责.3. 划分职责的原则:行为不同用类区分,数据不同用对象区分老张类     开车类驾驶方法   行驶方法张无忌对象    赵敏对象教4. 语法--1. 直接创建对象class A:def func01():b = B()b.func02()class B:def func02():pass--2.  在构造函数中创建对象class A:def __init__():self.b = B()def func01():self.b.func02()class B:def func02():pass--3. 通过参数传递对象class A:def func01(c):c.func02()class B:def func02():passa = A()a.func01(  B()  )
"""练习2:以面向对象思想,描述下列情景.玩家攻击敌人,敌人受伤(头顶爆字).
"""
class Player:def attack(self,target):print("发起攻击")target.damage() # 跨类调用class Enemy:def damage(self):print("头顶爆字")p = Player()
e = Enemy()
p.attack(e)   #发起攻击\n头顶爆字
"""练习4:以面向对象思想,描述下列情景.张无忌教赵敏九阳神功赵敏教张无忌玉女心经张无忌工作挣了5000元赵敏工作挣了10000元思想:张无忌与赵敏行为相同
"""class Person:def __init__(self, name=""):self.name = namedef teach(self, other, skill):print(self.name, "教", other.name, skill)def work(self, money):print(self.name, "工作挣了", money)# 对象区分数据不同
zwj = Person("张无忌")
zm = Person("赵敏")zwj.teach(zm, "九阳神功")   #张无忌 教 赵敏 九阳神功
zm.teach(zwj, "玉女心经")   #赵敏 教 张无忌 玉女心经zwj.work(5000)   #张无忌 工作挣了 5000
zm.work(10000)   #赵敏 工作挣了 10000
单项调用

Player调Enemy

"""在玩家攻击敌人时,传递数据以面向对象思想,描述下列情景.玩家(攻击力)攻击敌人(血量),敌人受伤(减血,头顶爆字,还有可能死亡)."""
"""
class Player:def attack(self,target): # 2print("发起攻击")target.damage()class Enemy:def damage(self): # 3         #  ?print("头顶爆字")p = Player()
e = Enemy()
# 由使用决定Player调用Enemy
p.attack(e)# 1
""""""
class Player:def __init__(self, atk=0):self.atk = atkdef attack(self, target):print("发起攻击")target.damage(self) # 将玩家传入到敌人类中class Enemy:def __init__(self, hp=0):self.hp = hpdef damage(self, other):self.hp -= other.atk    #调用玩家atk使用print("头顶爆字")if self.hp <= 0:self.death()def death(self):print("掉金币")p = Player(50)
e = Enemy(100)
p.attack(e)
p.attack(e)
"""class Player:def __init__(self, atk=0):self.atk = atkdef attack(self, target):print("发起攻击")target.damage(self.atk)  # 将玩家的攻击力传入到敌人类中class Enemy:def __init__(self, hp=0):self.hp = hpdef damage(self, value):self.hp -= value  #直接使用atkprint("头顶爆字")if self.hp <= 0:self.death()    #同一个类里调用self.def death(self):print("掉金币")p = Player(50)
e = Enemy(100)
p.attack(e)
p.attack(e)发起攻击
头顶爆字
发起攻击
头顶爆字
掉金币
互相调用(反面举例,了解)
"""以面向对象思想,描述下列情景.练习:玩家(攻击力)攻击敌人(血量),敌人受伤(减血,头顶爆字,还有可能死亡[掉金币]).敌人(攻击力)攻击玩家(血量),玩家受伤(减血,碎屏,还有可能死亡[游戏结束]).
"""class Player:def __init__(self, hp=0, atk=0):self.atk = atkself.hp = hpdef attack(self, target):print("发起攻击")target.damage(self.atk)def damage(self, value):print("碎屏")self.hp -= valueif self.hp <= 0:self.death()def death(self):print("游戏结束")class Enemy:def __init__(self, hp=0, atk=0):self.hp = hpself.atk = atkdef damage(self, value):self.hp -= valueprint("头顶爆字")if self.hp <= 0:self.death()def death(self):print("掉金币")def attack(self, target):print("发起攻击")target.damage(self.atk)p = Player(500, 50)
e = Enemy(100, 20)
# 玩家打一次敌人
p.attack(e)
# 敌人打一次玩家
e.attack(p)
print("玩家血量:", p.hp)
print("敌人血量:", e.hp)发起攻击
头顶爆字
发起攻击
碎屏
玩家血量: 480
敌人血量: 50

MVC模型(model view controller)

MVC模型(model view controller),数据模型类、界面视图类、逻辑控制类。

分配职责:
界面视图类:负责处理界面逻辑,比如显示菜单,获取输入,显示结果等。
逻辑控制类:负责存储学生信息,处理业务逻辑。比如添加、删除等
数据模型类:定义需要处理的数据类型。比如学生信息。

行业默认格式

class xxxView:def ...:class xxxController:def ...:class xxxModel:def ...:# 入口
view = StudentView()
view.main()

class内的设计步骤

第一步:定义功能函数若干,同时进行
第二步:创建调用连接
第三步:数据传递调用
学生信息管理系统MVC
class StudentModel:class StudentView:"""学生视图:输入/输出学生信息"""
class StudentController:"""学生控制器:处理核心功能,存储..."""
# 入口
view = StudentView()
view.main()

alt + 回车: 代码生成快捷键。先写出调用函数代码,再将光标停留在函数上alt + 回车快捷键生成定义函数代码

class StudentModel:def __init__(self, name="", age=0, score=0.0, sid=0):self.name = nameself.age = ageself.score = score# 由系统决定的全球唯一标识符(不是用户输入的)self.sid = sidclass StudentView:"""学生视图:输入/输出学生信息"""def __init__(self):self.controller = StudentController()    #第二步:创建调用连接def display_menu(self):            print("按1键录入学生信息")print("按2键显示学生信息")print("按3键删除学生信息")print("按4键修改学生信息")print("按5键根据成绩显示学生信息")def select_menu(self):item = input("请输入选项:")if item == "1":self.input_student()elif item == "2":# 先写出调用函数代码,再选中函数alt + 回车快捷键生成定义函数代码self.display_students()elif item == "3":self.delete_student()elif item == "4":self.set_student()elif item == "5":self.order_by_score()def input_student(self):#第一步:定义功能函数若干stu = StudentModel()   stu.name = input("请输入学生姓名:")stu.age = int(input("请输入学生年龄:"))stu.score = int(input("请输入学生成绩:"))self.controller.add_student(stu)   #第三步:数据传递调用,然后去StudentController()执行add_student()def main(self):       #让入口一直使用while True:self.display_menu()self.select_menu()def display_students(self):for item in self.controller.list_student:print(f"{item.name}的编号是{item.sid},年龄是{item.age},成绩是{item.score}")def delete_student(self):sid = int(input("请输入需要删除的学生编号:"))if self.controller.remove_student(sid):print("删除成功")else:print("删除失败")def set_student(self):stu = StudentModel()stu.sid = input("请输入学生编号:")stu.name = input("请输入学生姓名:")stu.age = int(input("请输入学生年龄:"))stu.score = int(input("请输入学生成绩:"))if self.controller.update_student(stu):print("修改成功")else:print("修改失败")def order_by_score(self):self.controller.ascending_order()self.display_students()class StudentController:"""学生控制器:处理核心功能,存储..."""def __init__(self):self.start_id = 100self.list_student = []def add_student(self, new_stu):# 设置学生编号(自增长)self.start_id += 1new_stu.sid = self.start_id# 追加到列表中self.list_student.append(new_stu)def remove_student(self, sid):"""在列表中删除学生信息:param sid: 学生编号:return: 是否成功"""for i in range(len(self.list_student)):if self.list_student[i].sid == sid:del self.list_student[i]return True  # 删除成功return False  # 删除失败def update_student(self, stu):""":param stu::return:"""for i in range(len(self.list_student)):if self.list_student[i].sid == stu.sid:# self.list_student[i].name = stu.name# self.list_student[i].age = stu.age# self.list_student[i].score = stu.scoreself.list_student[i].__dict__ = stu.__dict__return Truereturn Falsedef ascending_order(self):for r in range(len(self.list_student) - 1):for c in range(r + 1, len(self.list_student)):if self.list_student[r].score > self.list_student[c].score:self.list_student[r], self.list_student[c] = self.list_student[c], self.list_student[r]# 入口
view = StudentView()
view.main()

练习

练习:商品信息管理系统商品名称商品单价商品编号(1)输入商品信息V:显示菜单,选择菜单,获取信息C:添加信息M:商品模型(2)添加商品信息C:在add_commodity方法中设置cid追加到列表中(3)显示商品信息V:选择菜单,打印商品列表(4)删除商品信息V:选择菜单,获取编号/显示成功或失败C:移除信息(5)修改商品信息V:选择菜单,获取信息/显示成功或失败C:修改信息(6)根据单价升序排列V:选择菜单,调用C的排序算法,显示商品C:排序算法
"""商品信息管理系统
"""
#按需求依次写,这里是完整的代码class CommodityModel:"""商品模型:包装具体商品信息"""def __init__(self, name="", price=0, cid=0):self.name = nameself.price = priceself.cid = cidclass CommodityView:"""商品视图:处理商品界面逻辑,例如:输入输出商品信息"""def __init__(self):self.controller = CommodityController()def display_menu(self):print("按1键录入商品信息")print("按2键显示商品信息")print("按3键删除商品信息")print("按4键修改商品信息")print("按5键根据单价对商品信息排序")def select_menu(self):item = input("请输入选项:")if item == "1":self.input_commodity()elif item == "2":self.display_commoditys()elif item == "3":self.delete_commodity()elif item == "4":self.set_commodity()def input_commodity(self):cmd = CommodityModel()cmd.name = input("请输入商品名称:")cmd.price = int(input("请输入商品单价:"))self.controller.add_commodity(cmd)def main(self):while True:self.display_menu()self.select_menu()def display_commoditys(self):for item in self.controller.list_commodity:print("%s的编号是%s,单价是%s" % (item.name, item.cid, item.price))def delete_commodity(self):cid = int(input("请输入需要删除的编号:"))if self.controller.remove_commodity(cid):print("删除成功")else:print("删除失败")def set_commodity(self):cmd = CommodityModel()cmd.cid = int(input("请输入商品编号:"))cmd.name = input("请输入商品名称:")cmd.price = int(input("请输入商品单价:"))if self.controller.update_commodity(cmd):print("修改成功")else:print("修改失败")class CommodityController:"""商品控制器:处理商品业务逻辑,例如:存储信息"""def __init__(self):self.start_id = 100self.list_commodity = []def add_commodity(self, new_cmd):new_cmd.cid = self.start_idself.start_id += 1self.list_commodity.append(new_cmd)def remove_commodity(self, cid):""":param cid::return:"""for i in range(len(self.list_commodity)):if self.list_commodity[i].cid == cid:del self.list_commodity[i]return Truereturn Falsedef update_commodity(self, cmd):""""""for i in range(len(self.list_commodity)):if self.list_commodity[i].cid == cmd.cid:self.list_commodity[i].__dict__ = cmd.__dict__return Truereturn Falseview = CommodityView()
view.main()

类成员

类变量(使用较少,了解为主)

(1) 定义:在类中,方法外。
class 类名:变量名 = 数据(2) 调用:类名.变量名 #  不建议通过对象访问类变量
(3) 特点:随类的加载而加载,存在优先于对象,只有一份,被所有对象共享。
(4) 作用:描述所有对象的共有数据。

类方法 隐式传递

(1) 定义:@classmethoddef 方法名称(cls,参数):方法体(2) 调用: 类名.方法名(参数) # 不建议通过对象访问类方法
"""小结 - Python语言变量
"""
# 全局变量:整个文件可见
data01 = 1def func01():# 局部变量:一个函数内部可见data02 = 2class MyClass:# 类变量:通过类访问data04 = 4def __init__(self):# 实例变量:通过对象访问self.data03 = 3# 局部变量:一个函数内部可见data05 = 5
class MyClass:data01 = 1 # 类变量,随类的加载而加载def __init__(self):self.data02 = 2  # 实例变量,使用时存放到栈帧中MyClass.data01 += 1self.data02 += 1m01 = MyClass()# data02:2->3   data01:1-2
m02 = MyClass()# data02:2->3   data01:2-3
print(m02.data02)  # 3
print(MyClass.data01)  # 3

类方法使用

至少有一个形参,第一个形参用于绑定类,一般命名为'cls'
使用@classmethod修饰的目的是调用类方法时可以隐式传递类。
类方法中不能访问实例成员,实例方法中可以访问类成员。
class ICBC:"""工商银行"""# 类变量:表达不同个体相同数据  [总行(大家的)]total_money = 1000000# 实例方法
""" def print_total_money(cls):  print("总行的钱:", ICBC.total_money)
"""def __init__(self, name="", money=0):# 实例变量:表达不同个体不同数据  [支行(自己的)]self.name = nameself.money = money# 支行创建时,总行的钱减少ICBC.total_money -= self.money# 类方法@classmethoddef print_total_money(cls):# 建议:在类方法中通过cls操作类变量print("总行的钱:", cls.total_money) #不用ICBC.调用,更简短"""#实例方法def print_total_money2():print("总行的钱:", ICBC.total_money)  #实例方法使用的是ICBC"""tian_tian = ICBC("天坛支行", 100000)
# print("总行的钱:", ICBC.total_money)
ICBC.print_total_money()
xi_dan = ICBC("西单支行", 200000)
# print("总行的钱:", ICBC.total_money)
ICBC.print_total_money()# print_total_money(ICBC)

创建对象计数器,统计构造函数执行的次数

#创建对象计数器,统计构造函数执行的次数,
class Wife:count = 0@classmethoddef print_count(cls):print(f"总共娶了{cls.count}个老婆")def __init__(self, name):self.name = nameWife.count += 1w01 = Wife("双儿")
w02 = Wife("阿珂")
w03 = Wife("苏荃")
w04 = Wife("丽丽")
w05 = Wife("芳芳")
Wife.print_count()  # 总共娶了5个老婆
#看不懂可以先了解,上下对比classmethod
class StudentController:"""学生控制器:处理核心功能,存储..."""def __init__(self):self.start_id = 100self.list_student = []def add_student(self, new_stu):# 设置学生编号(自增长)self.start_id += 1    #classmethodnew_stu.sid = self.start_id# 追加到列表中self.list_student.append(new_stu)
#########   上下对比classmethod   #####################
class StudentController:__start_id = 100  # 大家的:系统不同界面使用的学生编号是一份(连续增加)@classmethoddef __set_student_id(cls, stu):cls.__start_id += 1stu.sid = cls.__start_id   #StudentController替换成cls使用def __init__(self):self.__list_student = []  # 自己的:系统不同界面使用自己数据(可以显示不同数据)@property  # 只读属性:View类只能读取,不能修改def list_student(self):return self.__list_studentdef add_student(self, new_stu):# 设置学生编号StudentController.__set_student_id(new_stu)# 追加到列表中self.__list_student.append(new_stu)
"""信息管理系统
"""class EmployeeModel:def __init__(self, eid=0, did=0, name="", money=0):self.eid = eidself.did = didself.name = nameself.money = moneydef __str__(self):return str(self.__dict__)def __gt__(self, other):return self.money > other.moneydef __eq__(self, other):return self.eid == other.eidclass EmployeeController:"""员工信息控制器:业务逻辑,核心功能"""__start_id = 1001  # 类变量:无论多少对象,只有一份@classmethoddef __set_employee_id(cls, emp):emp.eid = cls.__start_idcls.__start_id += 1def __init__(self):self.__all_employee = []  # 实例变量:每个对象都有一份@propertydef all_employee(self):return self.__all_employeedef add_employee(self, emp):"""添加商品信息:param employee:需要添加的商品信息"""EmployeeController.__set_employee_id(emp)self.__all_employee.append(emp)def remove_employee(self, eid):"""根据商品编号删除商品信息:param cid:商品编号:return:是否删除成功"""emp = EmployeeModel(eid=eid)if emp in self.all_employee:self.all_employee.remove(emp)return Truereturn Falsedef update_employee(self, emp):for item in self.__all_employee:if item.eid == emp.eid:item.__dict__ = emp.__dict__return Truereturn Falsedef ascending_order(self):self.all_employee.sort()class EmployeeView:"""员工信息视图:界面逻辑,输入输出"""def __init__(self):self.__controller = EmployeeController()def main(self):while True:self.__display_menu()self.__select_menu()def __display_menu(self):print("1 添加员工")print("2 显示员工")print("3 删除员工")print("4 修改员工")print("5 根据薪资排序")def __select_menu(self):item = input("请输入您的选项:")if item == "1":self.__input_employee()elif item == "2":self.__display_employees()elif item == "3":self.__delete_employee()elif item == "4":self.__modify_employee()elif item == "5":self.__order_by_score()def __order_by_score(self):self.__controller.ascending_order()self.__display_employees()def __input_employee(self):employee = EmployeeModel()employee.name = input("请输入员工名称:")employee.did = int(input("请输入部门编号:"))employee.money = int(input("请输入员工工资:"))self.__controller.add_employee(employee)def __display_employees(self):for item in self.__controller.all_employee:print(item)def __delete_employee(self):cid = int(input("请输入员工编号:"))if self.__controller.remove_employee(cid):print("删除成功")else:print("删除失败")def __modify_employee(self):employee = EmployeeModel()employee.eid = int(input("请输入员工编号:"))employee.name = input("请输入员工名称:")employee.did = int(input("请输入部门编号:"))employee.money = int(input("请输入员工工资:"))if self.__controller.update_employee(employee):print("修改成功")else:print("修改失败")view = EmployeeView()
view.main()
"""2. 以面向对象思想,描述下列情景:情景:手雷爆炸,可能伤害敌人(头顶爆字)或者玩家(碎屏)。变化:还可能伤害房子、树、鸭子....要求:增加新事物,不影响手雷.画出架构设计图
"""# --------------架构师--------------------
class Grenade:def explode(self, target):print("爆炸")# 先确定用法# 判断传入的对象是一种攻击目标if isinstance(target,AttackTarget):# 编码时,调用是父类# 运行时,执行是子类target.damage()class AttackTarget:def damage(self):pass# --------------程序员--------------------
class Player(AttackTarget):# 后实现功能def damage(self):print("碎屏")class Enemy(AttackTarget):def damage(self):print("头顶爆字")# --------------入口--------------------
grenade = Grenade()
p = Player()
grenade.explode(p)  #爆炸\n碎屏
grenade.explode(Enemy()) #爆炸\n头顶爆字
grenade.explode("大爷") #爆炸

封装、集成、多态回顾

    面向对象三大特征:封装:根据需求划分为多个类    [分]例如:创建Person/Car/Airplane类继承:将多个变化的类型抽象为一个概念   [隔]例如:创建父类Vehicle将多个变化类型的行为统一例如:统一Car/Airplane类型的transport方法隔离客户端代码,与多个变化类型例如:隔离Person与Car/Airplane多态:对于父类同一行为,在不同的子类中有不同的实现例如:对于Vehicle的transport方法,在Car/Airplane类中有不同实现多个变化类型通过重写实现具体功能   [做]例如:Car/Airplane重写transport方法的内容
"""需求:一家公司有如下几种岗位:程序员:底薪 + 项目分红测试员:底薪 + Bug数*5创建员工管理器,实现下列要求:(1)存储多个员工(2)打印所有员工姓名(3)计算所有员薪资练习1:写出下列代码的面向对象三大特征思想封装: 创建EmployeeController/Programmer/Tester继承: 创建父类Employee统一Programmer/Tester类型的calculate_salary方法隔离EmployeeController与Programmer/Tester多态:对于Employee的calculate_salary方法,在Programmer/Tester类中有不同实现Programmer/Tester重写calculate_salary方法的内容"""class EmployeeController:"""员工管理器"""def __init__(self):self.__list_employee = []@propertydef list_employee(self):return  self.__list_employeedef add_employee(self, emp):if isinstance(emp, Employee):  #判断是否继承父类,不是不添加。下面的add大爷操作不会被执行self.__list_employee.append(emp)def get_total_salary(self):total_salary = 0for item in self.__list_employee:# 体会多态:编码时调用父#         运行时执行子total_salary += item.calculate_salary()return total_salaryclass Employee:def __init__(self, name="", base_salary=0):self.name = nameself.base_salary = base_salarydef calculate_salary(self):passclass Programmer(Employee):def __init__(self, name, base_salary, bonus):super().__init__(name, base_salary)self.bonus = bonusdef calculate_salary(self):# 底薪 + 项目分红salary = self.base_salary + self.bonusreturn salaryclass Tester(Employee):def __init__(self, name, base_salary, bug_count):super().__init__(name, base_salary)self.bug_count = bug_countdef calculate_salary(self):# 底薪 + Bug数*5salary = self.base_salary + self.bug_count * 5return salarycontroller = EmployeeController()
controller.add_employee(Programmer("张三", 10000, 1000000))
controller.add_employee(Tester("李四", 8000, 300))
controller.add_employee("大爷")
print(controller.get_total_salary())
for item in controller.list_employee:print(item.name)
"""创建图形管理器-- 记录多种图形(圆形、矩形....)-- 提供计算总面积的方法.
"""class GraphicsController:def __init__(self):self.__list_graphics = []@propertydef list_graphics(self):return self.__list_graphicsdef add_graphics(self, graph):# if isinstance(graph,Graphics):self.__list_graphics.append(graph)def get_total_area(self):total_area = 0for item in self.__list_graphics:# 调用父,执行子(添加的子类对象)total_area += item.calculate_area()return total_areaclass Graphics:def __init__(self, name=""):self.name = namedef calculate_area(self):passclass Rectangle(Graphics):def __init__(self, name, l, w):super().__init__(name)self.l = lself.w = wdef calculate_area(self):return self.l * self.wclass Circle(Graphics):def __init__(self, name, r):super().__init__(name)self.r = rdef calculate_area(self):area = 3.14 * self.r ** 2return areacontroller = GraphicsController()
controller.add_graphics(Rectangle("大矩形", 7, 8))
controller.add_graphics(Circle("圈圈", 5))for item in controller.list_graphics:print(item.name)print(controller.get_total_area())

多继承: 隔离多个维度上的变化,正常情况下从左到右继承,python中使用.mro()查看实际继承顺序

"""同名方法在多继承中调用顺序
"""class A:def func01(self):print("A-func01")class B(A):def func01(self):print("B-func01")super().func01()class C(A):def func01(self):print("C-func01")super().func01()class D(B, C):def func01(self):print("D-func01")super().func01()# 通过类名调用指定类型中的函数C.func01(self)d = D()
d.func01()  # D  B  C# 类型记录了函数调用顺序
print(D.mro())
"""小结-面向对象一. 语法class 类名:类变量 = 数据@classmethoddef 类方法(cls):通过 cls.类变量 操作类变量def __init__(self,参数):self.实例变量 = 参数def 实例方法(self):通过 self.实例变量 操作数据对象 = 类名(数据)对象.实例变量对象.实例方法()类名.类变量类名.类方法()二. 设计思想封装:根据需求划分为多个类继承:统一多个变化类型,隔离客户端代码与多个变化类型多态:多个变化类型通过重写实现具体功能目标:满足开闭原则允许增加新功能,但是不修改客户端代码
"""

pt04-object-oriented相关推荐

  1. Java OOP(Object Oriented Programming)个人理解及总结

    面向对象编程(Object Oriented Programming,OOP,面向对象程序设计) 其三大特征:封装,继承,多态: 封装:解决数据的安全问题. 继承:解决代码的重用问题. 多态:解决程序 ...

  2. Python编程基础:第三十九节 面向对象编程Object Oriented Programming

    第三十九节 面向对象编程Object Oriented Programming 前言 实践 前言 到目前为止我们都是函数式编程,也即将每一个功能块写为一个函数.其实还有一种更常用的编程方式被称为面向对 ...

  3. Coursera课程Python for everyone:Quiz: Object Oriented Programming

    Object Oriented Programming 11 试题 1. Which came first, the instance or the class? instance class fun ...

  4. OO开发思想:面向对象的开发方法(Object oriented,OO)

    面向对象的开发方法(Object oriented,OO)认为是好文章吧,拿来分享一下(转载) 面向对象的开发方法(Object oriented,OO) 从事软件开发的工程 师们常常有这样 的体会: ...

  5. 面对对象编程(OOP, Object Oriented Programming)及其三个基本特性

    一千个读者,一千个哈姆雷特.对于面对对象编程,书上都会告诉我们它有三个基本特性,封装,继承,多态,但谈起对这三点的见解,又是仁者见仁智者见智,感觉还是得多去编程中体验把 . 面向对象编程(OOP, O ...

  6. 面向对象编程(Object Oriented Programming)概念总结及延伸(一)

    1.介绍 笔者的梦想是成为一个架构师,但是要成为一个合格的架构师是相当不易的,它既需要丰富的项目经验也需要不断地吸取新的知识,而且在这过程中我们也要不断巩固基础知识.我也注意到了,现在主流的文章大都集 ...

  7. Re: Object Oriented

    面向对象(Object Oriented,OO)是软件开发方法.面向对象的概念和应用已超越了程序设计和软件开发,扩展到如数据库系统.交互式界面.应用结构.应用平台.分布式系统.网络管理结构.CAD技术 ...

  8. Java SE 008 理解面向对象程序设计 (Inside Object Oriented Programming)

    Java SE 008 理解面向对象程序设计 (Inside Object Oriented Programming) 前言:此笔记为圣思园张龙老师讲述的java视频课程笔记,自己看视频学习时记录的, ...

  9. Java基础篇--面向对象(Object Oriented)

    Java基础篇--面向对象(Object Oriented) 1. 面向对象概念 1.1 什么事面向对象 1.2 理解面向对象 1.3 面向对象的特点 1.4 面向对象开发设计特征 2. 类与对象 2 ...

  10. python Object Oriented Programming

    python 知识点整理(五) 本文只是对python部分知识点进行学习和整理 本篇主要是针对python的Object Oriented Programming的总结 本文目录 python 知识点 ...

最新文章

  1. Android中的Service组件详解
  2. 渲染器跑分_这一次会挤牙膏吗?9400F/10400跑分对比
  3. MySQL数据库语句总结
  4. 程序员面试金典 - 面试题 16.06. 最小差(排序+双指针)
  5. java字符串字节_Java中字符串与byte数组之间的相互转换
  6. python中yaml模块的使用_详解Python yaml模块
  7. 在文本框的光标处插入指定的文本(兼容IE6和Firefox)
  8. AIML框架 初探
  9. 计蒜客1185出书最多
  10. Java 微信公众号消息推送(从零开始)
  11. 《乱世中的美神》梁衡
  12. Cocos Creator 安卓复制功能
  13. Documentation
  14. Linux debug 常用命令
  15. 当程序员这么多年,我学到了25条人生经验
  16. 库卡工业机器人负载曲线图_DC电机性能曲线图
  17. 使用CactiEZ监控RHEL5服务器
  18. 部门经理-项目经理-技术经理-产品经理
  19. 《手把手教你学嵌入式无人机》——2.航模遥控器通信协议
  20. 【大数据开发】供应链之CRM、OMS、WMS、SRM、SCM

热门文章

  1. jqWEUI的select组件加载后端数据为items
  2. 校园图书馆模拟器极其简陋版
  3. 第十届(2022年)全国大学生机械创新设计大赛参赛须知
  4. 回顾HTML5省技能大赛(html5交互融媒体内容设计与制作)
  5. 一款非常漂亮影视在线解析源码后台
  6. 古老CPU启示录-第一款单芯片微处理器8080
  7. 椭圆标准方程生成算法
  8. Windows下使用bat批处理文件实现进程守护
  9. Pc端扫码登入步骤解析
  10. ES6转ES5 你需要Babel