练习代码仓库地址: https://gitee.com/yangpengfi/pythonStudy/tree/master (day5\day6)
面向对象介绍
- 世界万物,皆可分类
- 世界万物,皆为对象
- 只要是对象,肯定属于某种类
- 只要是对象,肯定有属性
为什么要用面向对象开发?
- 编程:语法+数据结构+算法
- 编程范式:面向过程和面向对象、函数式编程
- 面向过程:多用于简单的、一次性的任务
- 面向对象:是利用‘类’和‘对象’来创建各种模型来对真实世界的描述,多用于功能复杂的
类、对象
class
- 一个类即是对一类有相同属性的对象的抽象、蓝图、原型(用来描述具有相同的属性和方法的对象的集合)。在类中定义了这些对象都具备的属性和共同方法。对象是类的实例。
object
- 一个对象即是一个类的实例化后实例,一个类必须经过实例化后方可在程序中调用,一个类可以实例化多个对象,每个对象亦可以有不同的属性
- 对象:通过类定义的数据结构实例。对象包括两个数据成员(类变量和实例变量)和方法。
面向对象的特性:封装、继承、多态
-
封装:在类中对数据的赋值、内部调用对外部用户是透明的,这使类变成了一个胶囊或容器,里面包含着类的数据和方法
- 方法:类中定义的函数。
- 类变量:类变量在整个实例化的对象中是公用的。类变量定义在类中且在函数体之外。类变量通常不作为实例变量使用。
- 数据成员:类变量或者实例变量用于处理类及其实例对象的相关的数据。
- 方法重写:如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫方法的覆盖(override),也称为方法的重写。
- 局部变量:定义在方法中的变量,只作用于当前实例的类。
- 实例变量:在类的声明中,属性是用变量来表示的。这种变量就称为实例变量,是在类声明的内部但是在类的其他成员方法之外声明的。
- 实例化:创建一个类的实例,类的具体对象。
- 类的专有方法:
__init__ : 构造函数,在生成对象时调用,做一些类的初始化工作。对象实例化r1 = Role("小米","警察","AK47")相当于Role(r1,"小米","警察","AK47")返回r1.name,r1.role...。传进来的实参都是实例变量(静态属性)。作用域:实例本身 __del__ : 析构函数,释放对象、销毁的时候自动执行的,通常用于做一些收尾工作,如关闭一些数据库链接,关闭临时文件等 __doc__:获取类的描述信息 __module__:表示当前操作的对象在哪个模块 __class__:表示当前操作的对象的类是什么 __call__:打印类里的所有属性(对象实例化后的对象加()来执行call方法) __str__:如果一个类中定义了__str__方法,那么在打印对象时,默认输出该方法的返回值 __getitem__、__setitem__、__delitem__:用于索引,如字典。分别表示获取、设置、删除数据 __new__、__metaclass__:__new__是用来创建实例的(会调用类的__init__),__metaclass__用来表示该类有谁实例化创建来的 __repr__ : 打印,转换 __setitem__ : 按照索引赋值 __getitem__: 按照索引获取值 __len__: 获得长度 __cmp__: 比较运算 __add__: 加运算 __sub__: 减运算 __mul__: 乘运算 __truediv__: 除运算 __mod__: 求余运算 __pow__: 乘方
-
继承:一个类可以派生出子类,在这个父类里定义的属性、方法自动被子类继承
- py2 经典类按深度优先来继承,新式类按广度优先来继承
- py3 经典类和新式类都是统一按广度优先来继承
-
多态:态是面向对象的重要特性,简单点说:“一个接口,多种实现”,指一个基类中派生出了不同的子类,且每个子类在继承了同样的方法名的同时又对父类的方法做了不同的实现,这就是同一种事物表现出的多种形态。
反射:
- 通过字符串映射或修改程序运行时的状态、属性、方法,有以下四个方法
getattr(object,name,default=none):根据字符串去获取obj对象里的对应的方法的内存地址 hasattr(object,name):判断一个对象obj里是否有对应的name_str字符串的方法 setattr(obj,y,z):相当于设置 obj.y = z delattr(x,y,z):删除对象属性
模块
1、定义:
- 模块:用来从逻辑上组织python代码(变量、函数、类、逻辑:实现一个功能),本质就是.py结尾的python文件(文件名:test.py,对应的模块名:test)
- 包:本质就是一个目录(必须带有一个__init__.py文件)
2、导入方法
import module_kk(一个)
import module_kk,module2_kk(多个)
from module_alex import *(导入模块内所有方法)
from module_alex import m1,m2,m3(导入模块内所有部分方法)
from module_kk import sayHello as say(给导入模块里的方法取一个别名)
3、import本质(路径搜索和搜索路径)
- 导入模块的本质就是把python文件解释一遍
- 导入包的本质就是执行该包下的__init__.py文件
4、导入优化
from module_kk import sayHello as say
5、模块的分类:
a:标准库(内置模块) 1)时间模块 b:开源模块(第三方模块) c:自定义模块
标准库:
1、time与datetime
- 在python中,通常有这几种方式来表示时间:
- 1)时间戳
- 2)格式化的时间字符串
- 3)元组(struct_time)共九个元素。
由于python的time模块实现主要调用c库,所以各个平台可能有所不同 time.struct_time(tm_year=2019, tm_mon=8, tm_mday=17, tm_hour=16, tm_min=35, tm_sec=14, tm_wday=5, tm_yday=229, tm_isdst=0)年、月、日、时、分、秒、周天、年天。需要说明的是struct_time实例的各个属性都是只读的,不可修改。
- time模块的方法:
time() -- 以浮点数的形式返回从1970开始的当前时间(以秒为单位)——时间戳 clock() -- 以浮点数的形式返回进程启动以来的CPU时间 sleep() -- 以浮点数表示的延迟数秒 gmtime() -- 将1970年以来的秒转换为UTC元组 localtime(time.time() + n*3600) -- 将1970年以来的秒转换为本地时间元组 (中国在东八时区即:UTC+8) asctime() -- 将时间元组转换为字符串 ctime() -- 将时间(以秒为单位)转换为字符串 mktime(struct_time_instance) -- 将本地时间元组转换为从1970年开始的秒的时间戳 strftime(time_format_str, struct_time_instance) -- 根据格式规范将时间元组转换为字符串 strptime(time_str, time_format_str) -- 根据格式规范将字符串解析为时间元组,如:time.strptime('2017-01-13 17:07', '%Y-%m-%d %H:%M') tzset() -- 更改本地时区
- datetime模块定义了以下几个类:
datetime.date -- 表示日期,常用的属性有:year, month和day datetime.datetime -- 表示日期时间 datetime.time -- 表示时间,常用属性有:hour, minute, second, microsecond datetime.timedelta -- 表示两个date、time、datetime实例之间的时间间隔,分辨率(最小单位)可达到微秒 datetime.tzinfo -- 时区相关信息对象的抽象基类。它们由datetime和time类使用,以提供自定义时间的而调整。 datetime.timezone -- Python 3.2中新增的功能,实现tzinfo抽象基类的类,表示与UTC的固定偏移量
2、random
- random()随机0到1之间的浮点数
- randint()
- randrange()
3、os 操作系统- NT或Posix的操作系统例程,这取决于我们所使用的系统。
- 所有功能从posix, nt或ce,如unlink, stat等。
- os.path 是posixpath还是ntpath
- os.name 是'posix', 'nt'或'ce'。
- os.curdir 用('.' or ':')表示当前目录的字符串。
- os.pardir ('..' or '::')是表示父目录的字符串
- os.sep ('/' or ':' or '\')路径名分隔符
- os.extsep (always '.')扩展器
- os.altsep (None or '/')备用路径名分隔符
- os.pathsep $PATH等中是否使用了组件分隔符
- os.linesep 文本文件中的行分隔符('\r' or '\n' or '\r\n')
- os.defpath 是可执行文件的默认搜索路径吗
- os.devnull 是空设备的文件路径吗('/dev/null', etc.)
- os.path处理文件路径
4、sys
5、shutil高级的文件、文件夹、压缩包处理模块(实际是对zipfile和tarfile)
6、json和pickle
- json用于字符串和python数据类型进行转换(用于和其他语言的数据交互)
- pickle用于python特有的类型和python的数据类型间进行转换
- 均提供dumps、dump、loads、load四个方法
7、shelve模块是一个简单的k、v将内存数据通过文件持久化的模块,可以持久化任何pickle可支持的python数据格式
8、xml处理模块
9、yaml写配置文件
10、Configparser处理模块:用于生成和修改配置文档
11、hashlib模块:用于加密相关的操作,提供md5(), sha1(), sha224(), sha256(), sha384(), and sha512()等算法
哈希对象有这些方法:
-
update(arg): 用arg中的字节更新哈希对象。重复调用是否等价于将所有调用连接在一起的单个调用的参数。
-
digest(): 返回传递给update()方法的字节摘要到目前为止。
-
hexdigest(): 与digest()类似,但返回的摘要是一个双长度的unicode对象,只包含十六进制数字。
-
copy(): 返回哈希对象的副本(克隆)。这可以用来有效地计算共享一个公共初始子字符串的字符串摘要。
例如,要获取字符串“Nobody inspects the spammish repetition”的摘要:
python import hashlib m = hashlib.md5() m.update(b"Nobody inspects") m.update(b" the spammish repetition") m.digest() # b'\xbbd\x9c\x83\xdd\x1e\xa5\xc9\xd9\xde\xc9\xa1\x8d\xf0\xff\xe9'
12、hmac他内部对我们创建key和内容再进行加密
13、re模块:正则表达式(动态,模糊的匹配)
- 描述:
-
此模块提供类似于。的正则表达式匹配操作在Perl中找到的。它支持8位和Unicode字符串;这两个正在处理的模式和字符串可以包含空字节和超出美国ASCII码范围的字符。
-
正则表达式可以包含特殊字符和普通字符。大多数普通字符,如“A”、“A”或“0”,都是最简单的正则表达式;他们只是匹配自己。你可以连接普通字符,使last匹配字符串“last”。
-
特殊字符是:
"." 匹配除换行以外的任何字符。 "^" 匹配字符串的开头。 "$" 匹配字符串末尾或字符串末尾换行之前的值。 "*" 匹配前面RE的0次或多次(贪婪)重复。贪心意味着它将匹配尽可能多的重复。 "+" 匹配前面RE的一个或多个(贪婪)重复。 "?" 匹配前面RE的0或1(贪婪)。 *?,+?,?? 前三个特殊字符的非贪婪版本。 {m,n} 匹配前面RE的m到n次重复。 {m,n}? 以上非贪婪版本。 "\\" 要么转义特殊字符,要么发出特殊序列的信号。 [] 表示一组字符。 作为第一个字符的“^”表示补集。 "|" 创建一个匹配A或B的RE。 (...) 匹配括号内的RE。 内容可以稍后在字符串中检索或匹配。 (?aiLmsux) 为RE设置A、I、L、M、S、U或X标志(参见下面)。 (?:...) 正则括号的非分组版本。 (?P<name>...) 组匹配的子字符串可以通过名称访问。 (?P=name) 匹配前面由名为name的组匹配的文本。 (?#...) 评论;忽略了。 (?=...) 如果匹配……匹配next,但不使用字符串。 (?!...) 如果匹配……不匹配。 (?<=...) 如果前面有…(必须是固定长度)。 (?<!...) 如果前面没有…(必须是固定长度)。 (?(id/name)yes|no) 如果与id/名称匹配的组匹配yes模式,则匹配(可选)no模式。
- 特殊序列由“\”和列表中的一个字符组成在下面。如果普通字符不在列表中,则结果RE将匹配第二个字符。
\number 匹配相同编号的组的内容。 \A 仅在字符串的开头匹配。 \Z 只匹配字符串的末尾。 \b 匹配空字符串,但仅在单词的开头或结尾。 \B 匹配空字符串,但不匹配单词的开头或结尾。 \d 匹配任何十进制数字;等价于字节模式或带ASCII标志的字符串模式的集合[0-9]。 在没有ASCII标志的字符串模式中,它将匹配Unicode数字的整个范围。 \D 匹配任何非数字字符;相当于 [^\d]。 \s 匹配任何空白字符;等同于[\t\n\r\f\v],以字节模式或带ASCII标志的字符串模式表示。 在没有ASCII标志的字符串模式中,它将匹配Unicode空白字符的整个范围。 \S 匹配任何非空白字符;相当于 [^\s] \w 匹配任何字母数字字符;相当于[a-zA-Z0-9_]的字节模式或带ASCII标志的字符串模式。 在没有ASCII标志的字符串模式中,它将匹配Unicode字母数字字符(字母加数字加下划线)的范围。 使用LOCALE,它将匹配set[0-9_]加上为当前LOCALE定义为字母的字符。 \W 匹配非[a-zA-Z0-9_]。 \\ 匹配文字反斜杠。
-
- 该模块导出以下功能:
match 将正则表达式模式匹配到字符串的开头。 fullmatch 将正则表达式模式匹配到所有字符串。 search 搜索字符串以寻找模式的存在。 sub 替换字符串中出现的模式。 subn 与下标相同,但也返回所做替换的个数。 split 根据模式的出现情况拆分字符串。 findall 查找字符串中出现的所有模式。 finditer 返回一个迭代器,为每个匹配生成一个匹配对象。 compile 将模式编译为RegexObject。 purge 清除正则表达式缓存。 escape 在字符串中反斜杠所有非字母数字。
- 该模块中的一些函数将标志作为可选参数:
A ASCII 对于字符串模式,让\w、\w、\b、\b、\d、\d匹配对应的ASCII字符类别(而不是整个Unicode类别,这是缺省值)。 对于字节模式,此标志是惟一可用的行为,不需要指定。 I IGNORECASE 执行不区分大小写的匹配。 L LOCALE 根据当前地区设置\w、\w、\b、\b。 M MULTILINE “^”匹配行开头(换行之后)和字符串。 “$”匹配行尾(换行之前)和字符串尾。 S DOTALL 匹配任何字符,包括换行符。 X VERBOSE 忽略空格和注释,让简历看起来更漂亮。 U UNICODE 仅供兼容性。忽略字符串模式(这是默认值),禁止字节模式。
- “(?P<name>...)”分组匹配 re.search("(?P<province>[0-9]{3})(?P<city>[0-9]{3})(?P<birthday>[0-9]{3})","410482195605203548").groupdict()
练习:选课系统
角色:学校、学员、课程、讲师
要求:
1.创建北京、上海2所学校
2.创建Linux,python,go3个课程,linux\py在北京开,go在上海开
3.课程包含周期、价格,通过学校创建课程
4.通过学校创建班级,班级关联课程、讲师
5.1创建学员时,选择学校关联班级
5.2创建讲师时,关联学校
6.提供两个角色接口
6.1学员视图,可以注册,交学费,选择班级
6.2讲师视图,讲师可管理自己的班级,上课时选择班级,查看班级学员列表,修改所管理的学员的成绩
6.3管理视图,创建讲师,创建班级,创建课程
7.上面的操作产生的数据都通过pickle序列化保存到文件里