""" 总结 - 面向对象 字面意思:考虑问题从对象的角度出发 谁?干嘛? 三大特征: 封装(分):将大的需求划分为多个类型----然后在属性,私有变量上再次封装 创建人类,汽车,飞机类 继承(隔):将相关概念的共性进行抽象、统一操作 创建交通工具隔离人类与汽车飞机等类的变化 多态(做):以重写的方式实现子类的个性 汽车,飞机重写交通工具的运输方法 价值:满足开闭原则(增加新变化点,客户端代码不变) 增加轮船、自行车,人类不需要改变 语法: class 类名: 类变量 = 数据 @classmethod def 类方法(cls): 操作类变量 def __init__(self,参数): self.实例变量 = 参数 def 实例方法(self): 操作实例变量 对象 = 类名(数据) 对象.实例变量 # 每个对象一份 [自己] 对象.实例方法() 类名.类变量 # 所有对象一份 [大家] 类名.类方法() """
作业 1. 三合一 2. 当天练习独立完成 3. 创建员工管理系统 -- 添加员工信息 -- 显示员工信息 -- 删除员工信息 -- 修改员工信息 4. 独立完成2048左右移动函数 class EmployeeModel: def __init__(self, eid=0, did=0, name="", money=0): self.eid = eid self.did = did self.name = name self.money = money def __str__(self): return f"员工编号{self.eid};部门编号{self.did};员工姓名{self.name};员工工资{self.money}" def __eq__(self, other): return self.eid == other class EmployeeView: def __init__(self, controller): self.controller = controller # type:EmployeeController def __display_menu(self): print("按1键录入员工信息") print("按2键显示员工信息") print("按3键删除员工信息") print("按4键修改员工信息") def __select_menu(self): item = input("请输入您的选项:") if item == "1": self.__input_employee() elif item == "2": self.__display_employee() elif item == "3": self.__delete_employee() elif item == "4": self.__modity_employee() def __input_employee(self): emp = EmployeeModel() emp.name = input("请输入员工姓名:") emp.did = int(input("请输入部门编号:")) emp.money = int(input("请输入员工薪资:")) self.controller.add_employee(emp) print("添加成功") def main(self): while True: self.__display_menu() self.__select_menu() def __display_employee(self): for item in self.controller.employees: print(item) def __delete_employee(self): num = int(input("请输入要删除的员工编号")) if self.controller.remove_employee(num): print("删除成功") else: print("删除失败") def __modity_employee(self): emp = EmployeeModel() emp.eid = int(input("请输入要修改的员工编号")) emp.money = int(input("请输入要修改员工的工资")) emp.did = int(input("请输入要修改员工的部门编号")) emp.name = input("请输入要修改员工的姓名") if self.controller.update_employ(emp): print("修改成功") else: print("修改失败") class EmployeeController: __start_id = 1000 @classmethod def __set_employee_id(cls, emp): emp.eid = cls.__start_id cls.__start_id += 1 def __init__(self): self.__employees = [] @property def employees(self): return self.__employees def add_employee(self, emp): EmployeeController.__set_employee_id(emp) self.__employees.append(emp) def remove_employee(self, num) -> bool: if num in self.__employees: self.__employees.remove(num) return True else: return False def update_employ(self, emp) -> bool: for item in self.__employees: if item.eid == emp.eid: item.__dict__ = emp.__dict__ return True return False controller = EmployeeController() view = EmployeeView(controller) view.main()
""" 2048核心算法 """ list_merge = [2, 0, 2, 0] def zero_to_end(): for i in range(len(list_merge) - 1, -1, -1): if list_merge[i] == 0: del list_merge[i] list_merge.append(0) def merge(): zero_to_end() for i in range(len(list_merge) - 1): if list_merge[i] == list_merge[i + 1]: list_merge[i] += list_merge[i + 1] del list_merge[i + 1] list_merge.append(0) # 3. 向左移动 map = [ [2, 0, 0, 2], [4, 2, 0, 2], [2, 4, 2, 4], [0, 4, 0, 4], ] def move_left(): global list_merge # 要这个修改全局变量,因此做一个声明,否则局部只能看不能改 for line in map: list_merge = line merge() # 4. 向右移动 move_right def move_right(): global list_merge for line in map: list_merge = line[::-1] # 切片读取数据时产生新列表 merge()# 处理的是新列表中数据,不是二维列表的行 line[::-1] = list_merge # 所以需要还原数据(list_merge --> map) # line = list_merge[::-1] # 错误,修改的是变量line不是map # line[:] = list_merge[::-1]#正确 move_right() print(map)
------------------------------------------------------------------------------------------------------------------------------
练习 2:将信息管理系统拆分为 4 个模块 student_info_manager_system.py
1)创建目录 student_info_manager_system
2)创建模块 bll,存储 XXController ---业务逻辑层 business logic layer
3)创建模块 usl,存储 XXView ---用户显示层 user show layer
4)创建模块 model,存储 XXModel
5)创建模块 main,存储调用 XXView 的代码
alt +enter功能:1.生成实例变量传入的参数
2.先写方法名称,再生成方法定义
3.导入模块
运行main就出现pycahe文件,帮你省去第二次运行还要编译的过程,节约时间与性能,直接从main开始解释起来。不用再浪费时间编译了,因此pyc文件夹里面没有生成的main编译文件。main文件叫主模块,一个项目里面应该包含这四个文件。
加载过程
1.在模块导入时,模块的所有语句会执行。
2.如果一个模块已经导入,则再次导入时不会重新执行模块内的语句。
模块变量
__doc__变量:文档字符串。 __name__变量:模块自身名字,可以判断是否为主模块。 当此模块作为主模块(第一个运行的模块)运行时,__name__绑定'__main__',不是主模 块,而是被其它模块导入时,存储模块名。
""" demo01.py 模块变量: python文件中的第一个字符串叫模块变量。用一个变量doc存住它 模块名称: 被导入的模块用name变量显示存储真实的模块名称,当前运行的叫主模块main名称,不论你叫什么名字的文件 """ import random #1.模块文档注释(往往在交互下使用),文件式直接 ctrl+q print(__doc__) #打印显示本文件的注释,即第一行汉字 print(random.__doc__)#打印显示random模块的注释 #模块名称:用于运行测试非主模块功能 import review print(review.__name__)#打印显示review print(__name__)#打印显示__main__ if __name__ == "__main__": print("当前模块不是主模块的话,从别的文件运行这行代码就不执行,别的文件测试代码内容不加载到主模块里面影响我们的主模块显示内容")
模块分类
-
内置模块(builtins),在解析器的内部可以直接使用。 如print
-
标准库模块,安装 Python 时已安装且可直接使用。如random
-
第三方模块(通常为开源),需要自己安装。如 numpy
-
用户自己编写的模块(可以作为其他人的第三方模块)
""" 标准库模块 - time 自己导入 """ import time # 1. 人类时间(时间元组): # (年,月,日,时,分,秒,星期,年的第几天,是否是夏令时) tuple_time = time.localtime() print(tuple_time[3]) # 时 print(tuple_time.tm_hour) # 时 print(tuple_time[-3]) # 星期 print(tuple_time.tm_wday) # 星期 print(tuple_time[:3]) # 年,月,日 # 2. 机器时间(时间戳): 1970年元旦~现在经过的秒数 # 1616037532.2794447 # 1616037713.6778865 print(time.time()) # 3. 时间戳->时间元组 # 语法:时间元组 = time.localtime( 时间戳 ) print(time.localtime(1616037532.2794447)) # 4. 时间元组-> 时间戳 # 语法:时间戳 = time.mktime(9个元素的元组) print(time.mktime((2021, 3, 18, 11, 34, 30, 0, 0, 0))) print(time.mktime(tuple_time)) # 5. 时间元组->字符串 # 语法:字符串 = time.strftime("格式", 时间元组) # 21/03/18 11:49:02 print(time.strftime("%y/%m/%d %H:%M:%S", tuple_time)) # 2021/03/18 11:48:56 print(time.strftime("%Y/%m/%d %H:%M:%S", tuple_time)) print(time.strftime("年份:%Y,月份:%m,天:%d %H:%M:%S", tuple_time)) # 6. 字符串->时间元组 # 语法:时间元组 = time.strptime(时间字符串,格式) time.strptime("2021/03/18 11:48:56", "%Y/%m/%d %H:%M:%S") print(time.strptime("11:48:56", "%H:%M:%S")) # print(time.strptime("11-48-56","%H:%M:%S")) # print(time.strptime("11:48","%H:%M:%S"))
""" 练习1:定义函数,根据年月日,计算星期。 输入:2020 9 15 输出:星期二 """ import time def get_week_name(year,month,day): """ 获取星期名称 :param year:年份 :param month:月份 :param day:天 :return:星期名称 """ # "2021/03/18 11:48:56","%Y/%m/%d tuple_time = time.strptime(f"{year}/{month}/{day}","%Y/%m/%d") index = tuple_time[-3] list_week_name = [ "星期一","星期二","星期三","星期四","星期五","星期六","星期日" ] return list_week_name[index] print(get_week_name(2021,3,18))
""" 练习2:定义函数,根据生日(年月日),计算活了多天. 输入:2010 1 1 输出:从2010年1月1日到现在总共活了3910天 """ import time def get_life_days(year, month, day): tuple_time = time.strptime(f"{year}/{month}/{day}", "%Y/%m/%d") life_second = time.time() - time.mktime(tuple_time) return life_second / 24 / 60 / 60 print("%.2f" % get_life_days(1995, 9, 25))
包 package 里面的init就是包的标志,创建包时候自动创建init文件
定义 将模块以文件夹的形式进行分组管理。
作用 让一些相关的模块组织在一起,使逻辑结构更加清晰。
""" 程序结构 1. 主模块:第一次运行的模块 2. 根目录:主模块 main.py所在文件夹 3. 目录结构: 项目根目录 多个包(文件夹) 多个模块(文件) 多个类 多个函数 多个语句 """ # 导入路径:从项目根目录开始 # 方式1: # import 包.模块 as 别名 import day15.package01.package02.module01 as m1 m1.func01() # 方式2: # from 包.模块 import 成员 from day15.package01.package02.module01 import func01 func01()
练习 1:
-
根据下列结构,创建包与模块。
my_project01 /
main.py
common/
init.py
list_helper.py
skill_system/
init.py
skill_deployer.py
skill_manager.py
-
在 main.py 中调用 skill_manager.py 中实例方法。
-
在 skill_manager.py 中调用 skill_deployer.py 中实例方法。
-
在 skill_deployer.py 中调用 list_helper.py 中类方法。
注意:导入什么就先执行导入里面的程序,依次向上递归。
init.py 文件
是包内必须存在的文件
会在包加载时被自动调用
作用
记录 import 包 语句需要导入的模块
""" 导入包 之前my_project01是精确到导入文件, 这里我们导入到包即可,目的是将包里面从 经常用到的模块成员封装到init里面, 需要在包的__init__.py文件中指定需要访问的成员 用户调用起来更加方便 """ # 方式1:import 包 as 别名 import package01.package02 as p p.module01.func01() # 方式2:from 包.包 import 成员 from package01.package02 import module01, func01 # 前提是init里面提前加入func01,就可以跨级别用了 module01.func01() func01()
练习 2:
-
根据下列结构,创建包与模块。
my_project 02/
main.py
common/
init.py
list_helper.py
skill_system/
init.py
skill_manager.py
-
通过导入包的方式,在 main.py 中调用 skill_manager.py 中实例方法。
-
通过导入包的方式,在 skill_manager.py 中调用 list_helper.py 中类方法。
搜索顺序
sys.path 提供的路径
""" 搜索顺序:用于查看导入包的错误路径检查 标蓝:把标蓝文件夹放在搜索路径里面 """ import sys # 导入搜索路径:["根目录",.....,等其他路径] # 每次导入时,都会遍历该列表, # 如果导入路径与列表中记录的路径,能够找到文件,则导入成功 print(sys.path)