Python DAY 12 重点知识总结 系统模块 面向对象
一 系统模块
一 time模块
import time
print(time.time()) #时间戳 1596432288.6838048 距离1970年1月1日的秒数
# 时间戳 <==> 时间元组
print(time.gmtime()) # 当前的时间元组
#time.struct_time(tm_year=2020, tm_mon=8, tm_mday=3, tm_hour=5, tm_min=27, tm_sec=2, tm_wday=0, tm_yday=216, tm_isdst=0)
print(time.gmtime(1590430000)) # 时间戳 => 时间元组
#time.struct_time(tm_year=2020, tm_mon=5, tm_mday=25, tm_hour=18, tm_min=6, tm_sec=40, tm_wday=0, tm_yday=146, tm_isdst=0)
t = time.localtime()
print(t) # 当地的时间元组
# time.struct_time(tm_year=2020, tm_mon=8, tm_mday=3, tm_hour=13, tm_min=31, tm_sec=46, tm_wday=0, tm_yday=216, tm_isdst=0)
print(t[0]) # 年 2020
print(t[1]) # 月 8
print(t[2]) # 日 3
# 时间元组 <==> 时间字符串
# 时间元组 ==> 时间字符串
t1 = time.localtime()
print(time.strftime('%Y-%m-%d %H:%M:%S',t1))
# 2020-08-03 13:52:04 在%Y和%m 之间的- 起分割作用 基本上都可以使用 比如'/'也可以作用为分割符
print(time.strftime('%Y %m/%d %H:%M:%S',t1)) #2020 08/03 13:56:45
# 格式化输出
print(time.asctime(t1)) # Mon Aug 3 13:57:58 2020
print(time.ctime(time.time())) # Mon Aug 3 13:58:49 2020
# time.sleep() 暂停相应时间 会堵塞程序
time.sleep(0.5) # 暂停0.5秒
#
'''
%y 两位数的年份表示(00-99)
%Y 四位数的年份表示(000-9999)
%m 月份(01-12)
%d 月内中的一天(0-31)
%H 24小时制小时数(0-23)
%I 12小时制小时数(01-12)
%M 分钟数(00-59)
%S 秒(00-59)
%a 本地简化星期名称
%A 本地完整星期名称
%b 本地简化的月份名称
%B 本地完整的月份名称
%c 本地相应的日期表示和时间表示
%j 年内的一天(001-366)
%p 本地A.M.或P.M.的等价符
%U 一年中的星期数(00-53)星期天为星期的开始
%w 星期(0-6),星期天为星期的开始
%W 一年中的星期数(00-53)星期一为星期的开始
%x 本地相应的日期表示
%X 本地相应的时间表示
%% %号本身
'''
二 datetime模块
import datetime
# 当前时间的日期对象
e = datetime.datetime.now()
print(e,type(e)) # #2020-08-03 14:12:01.468192 <class 'datetime.datetime'>
# 创建指定的日期对象
d = datetime.datetime(year=2030,month=1,day=2)
print(d) # 2030-01-02 00:00:00
print(d.year , d.month , d.day) # 日期 2013 1 2
print(e.hour , e.minute , e.second) # 时间 14 15 18
print(d.date() , d.time()) # 2030-01-02 00:00:00
print(d.timestamp()) # 时间戳
print(d.strftime(%Y-%m-%d)) # 格式化字符输出 2030-01-02
# 时间戳 => 日期对象
print(datetime.datetime.fromtimestamp(1893513600))
# 2030-01-02 00:00:00
# 时间差
d2 = datetime.timedelta(days = 7,hours = 10)
print(d + d2) # 2030-01-09 10:00:00
# 七天十小时之后的时间
print(d - d2) # 2029-12-25 14:00:00
# 七天十小时之前的时间
三 calendar模块
import calendar
c = calendar.calendar(2020, w=2, l=1 , c=2)
# w 为字体的大小/字的宽度
# l 为行与行之间的间距
# c 为两个月之间的间距 横向
# c月份间隔距离;w每日宽度间隔;l是每星期的行数
print(c) # 答应了一整年的日历
# 如:
'''
January February March
Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su
1 2 3 4 5 1 2 1
6 7 8 9 10 11 12 3 4 5 6 7 8 9 2 3 4 5 6 7 8
13 14 15 16 17 18 19 10 11 12 13 14 15 16 9 10 11 12 13 14 15
20 21 22 23 24 25 26 17 18 19 20 21 22 23 16 17 18 19 20 21 22
27 28 29 30 31 24 25 26 27 28 29 23 24 25 26 27 28 29
30 31
'''
j = calendar.month(2020,7)
print(j)
# 打印某一年的某一个月的日历
#
'''
July 2020
Mo Tu We Th Fr Sa Su
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
'''
# 判断是否为闰年
print(calendar.isleap(2020)) #True
print(calendar.isleap(2019)) #False
print(calendar.leapdays(1900,2020)) # 29
# Return number of leap years in range
print(calendar.monthcalendar(2020,7))
# [[0, 0, 1, 2, 3, 4, 5], [6, 7, 8, 9, 10, 11, 12], [13, 14, 15, 16, 17, 18, 19], [20, 21, 22, 23, 24, 25, 26], [27, 28, 29, 30, 31, 0, 0]]
print(calendar.monthrange(2020,7)) #(0,30)
#Return weekday (0-6 ~ Mon-Sun) and number of days (28-31) for year, month.
四 hashlib模块
import hashlib
# 加密算法
# md5 : 不可逆(不能解密),堆成加密(明文和密文一一对应)
# RSA : 非对称加密,需要公钥和私钥
# AES,DES :对称加密 可逆的 但是需要一个专门的key
# md5加密: 对字符串
m = hashlib.md5()
# print(m) #<md5 HASH object @ 0x0000027C17ABA080>
m.update('123456'.encode())
print(hexdigest()) # e10adc3949ba59abbe56e057f20f883e
二 面向对象
相对于面向过程
面向过程 : 考虑其过程 重点在于使用过程如何实现
面向对象 : 考虑谁来做 用什么来做
比如:小狗吃狗粮
用 面向过程 和面向对象的两种想法来写
# 小狗吃狗粮
# 面向过程 使用函数封装每个功能 然后按照顺序进行调用
def smell():
print('闻一闻')
def lick():
print('舔一舔')
def bite():
print('咬一咬')
smell()
lick()
bite()
# 面向对象 : 创建类将功能进行封装 然后再通过类的对象调用功能
class Dog:
name = '旺财'
def smell(self):
print(self.name,'闻一闻')
def lick(self):
print(self.name,'舔一舔')
def bite(self):
print(self.name,'咬一咬')
# 使用类 创建对象
dog = Dog()
print(dog.name)
dog.smell()
dog.lick()
dog.bite()
三 类和对象[掌握]
- 概述
- 类 多个具有特殊功能的个体的集合
- 对象 在一个类中 一个具有特殊功能的个题 能够帮忙解决某件特定的事情 也被称为实例[instance]
- 两者之间的关系 类用于描述一类对象的共同特征 而对象是类的具体存在[包含关系]
- 类和对象
- 类 泛指 指的是同一系列的事务
- 对象 特指 指的是一个具体存在的实例
- 创建类
- 属性: 变量 特征 静态的
- 方法: 函数 行为/功能 动态的
- 类中的方法和变量
- 类中的方法和变量是为了描述事物的行为和特征
- 类中定义的方法被称为成员 也被称为属性
- 成员变量: 类具有的特征
- 成员方法: 类具有的行为
- 类存在的意义 拥有相同特征和行为的对象可以抽取出来一个类 类的存在是为了创建一个具体的对象
- 注意的部分
- 类中的成员方法区别于普通方法:参数部分一定包含self,而且最好self出现在参数列表的第一个
- 调用函数的时候 self不需要被传参
- 除此之外 成员方法的用法和普通方法的使用完全相同 也可以设置默认参数或者关键字参数 不定长参数
- self:自己 , 代表类的实例[对象]
- 此处的self可以是任意的标识符 只不过为了结合其他的编程使用 习惯上使用self [self 只是一个参数 代表类本身 当然如果实在是要用一个a 也可以 但是习惯上使用self]
class Person(object): # object 可以不写
# 属性
name = '小明'
age = 10
# 方法
def eat(self):
print(self.name,'吃饭')
# 创建对象/实例
p = Person()
print(p.name) # 小明
print(p.age) # 10
p.eat() # 吃饭
p2 = Person()
p2.eat()
# self: 1. 不是关键字 只是一个形参 一般取名为self
# 2. 指向当前类的对象 等于当前类的对象
# 3. p调用eat时 self==p ; p2调用self时 self==p2
-
内存中的对象
p = Person()
说明:- 程序中定义的Person类型的变量p实际上是一个变量名 他被存在栈内存中 他只想实际的Person对象 而真正的Person对象则存放于堆内存中
- 类中的成员变量随着对象的出现而出现 随着对象的消失而消失
- 每个对象的成员变量会在堆空间中开辟一份自己的空间 相互之间互不影响
-
笔记
# 类
class Pig:
# 类属性
name = '佩奇'
likes = ['吃','睡']
# 构造函数 (初始化函数):
# 1. 这个函数会在对象创建时 自动被调用
# 2. 在这个函数中可以初始化属性
def __init__(self,name1,age1): # 这玩意就是每一个对象的初始化属性
self.name1 = name1
# 对象属性: 成员变量
self.age = age1 # 右边的age1是一个参数 形参
# self.age 是一个属性
self.name = '超人强'
self.likes2 = ['吃', '睡', '游泳']
def eat(self):
print(self.name,self.name1,self.age,'吃饭')
p3 = Pig('乔治',10)
print('1.',Pig.name,p3.name) # 1. 佩奇 超人强
# 如果在__init__ 内有和类属性同名的对象属性 使用对象调用时 会优先使用对象属性 如果对象属性中没有该名字的对象 则会在 类对象中寻找并使用
# 而使用类来调用时 类无法直接调用对象属性内的内容
# 在这个地方 Pig 里面传进去的参数会
# 直接进入__init__ 的参数里面 复制name1 , age1
p3.eat()
# 对象
# p1 = Pig()
# p1.eat() # 佩奇 吃饭
# p2 = Pig()
# p2.eat() # 佩奇 吃饭
# 类属性的调用
# print(p1.name) # 佩奇 对象.类属性
# print(Pig.name) # 佩奇 类名.类属性
print(p3.name1) # 乔治 对象,对象属性
# print(Pig.name1) # 报错 类.对象属性 错误 不能调用
# 修改对象属性
p3.name1 = '八戒'
print(p3.name1) # 八戒
# 修改类属性
# 错误案例
p3.name = '猪猪侠' # 对象不能修改类属性
print(Pig.name,p3.name) # 佩奇 猪猪侠
# 这个的意思是 p3.name 这个重新创建了一个 对象属性
# 所以调用的对象属性是猪猪侠 但是 Pig.name 可以看出 类属性并没有更改
# 正确方式
Pig.name = '猪猪侠'
print(Pig.name,p3.name) # 猪猪侠 猪猪侠
# 所以如果需要该改变类属性 那么必须用类来改 而不是使用对象来更改
# print(Pig.name,p3.name)
# 类属性是所有Pig对象(即该class对象) 共享的
p1 = Pig('佩奇',3)
p2 = Pig('乔治',2)
print(p1.likes) # ['吃', '睡']
print(p2.likes) # ['吃', '睡']
p1.likes.append('游泳')
print(p1.likes) # ['吃', '睡', '游泳']
print(p2.likes) # ['吃', '睡', '游泳']
# 对象属性不是共享的 对象属性是独立的
p1 = Pig('佩奇',3)
p2 = Pig('乔治',2)
print(p1.likes2) # ['吃', '睡', '游泳']
print(p2.likes2) # ['吃', '睡', '游泳']
p1.likes2.append('游泳')
print(p1.likes2) # ['吃', '睡', '游泳', '游泳']
print(p2.likes2) # ['吃', '睡', '游泳']
# 总结:1. 同一个类 更改类属性 不同的对象同时改变 即共享类属性
# 2. 同一个类 更改对象属性 不同的对象改变不同 不共享对象属性
解释:
- 对象属性和 类属性的基本解释
- 一个类里 有类属性 对象属性 和 方法 , 方法实际上对应的就是每一个函数定义
- 类属性 即为建立在类下 而不在函数中的属性 在这个例子里 name= ‘佩奇’ 以及 likes=[‘吃’,‘睡’] 就是类属性
- 对象属性 即被封装在各个函数内的参数, 这些参数会根据不同的输入 有不同的输出 常常出现的也是对象属性 在本例子里 name1,age1 参数就是属于对象属性
- _ init_ 这是一个十分特殊的函数 这个函数很像每一个兑现的初始化属性 一般出现在这个类的开头第一个函数 加入的是这个对象的初始化参数 比如在这个例子中 name1,age1 就是 关于传入Pig的基本属性 如p3的’乔治’和10 传入在_ init_ 里的便是这个
- 调用
- 类属性的调用 可以使用两种方法 1.对象.类属性 2. 类名.类属性
- 对象属性的调用 只能使用 对象.对象属性 来实现 如果使用 类.对象属性 则会报错
- 结论 : 在取类属性的时候 可以使用对象和类名 dot 类属性的方式来取 如果是取对象属性 则只能由相对应的对象dot对象属性来实现
- 关于属性修改
- 修改对象属性
直接使用对象dot对象属性 = ‘修改后的部分’
比如 : p3.name1 = ‘八戒’ - 修改类属性
- 对象不能修改类属性
- p3.name = ‘猪猪侠’ 这个的意思是重新创建了一个对象属性 所以调用对象属性是猪猪侠 但是Pig.name 可以看出 类属性并没有改变
- 正确的方式为 Pig.name = ‘猪猪侠’
所以如果需要改变类属性 那么必须使用类来改 而不是使用对象来更改
- 修改对象属性
- 对象属性不是共享的 对象属性独立 但是类属性的更改是共享的
- 同一个类的对象 类属性是共享的 意思就是说 当类属性改变后 所有对象中类属性都会跟着改变 比如本道题中的 p1.likes.append(‘游泳’) 再次操作后 对象中的类属性 都会改变
- 对象属性是相对独立的 如果更改了其中一个对象中的某个参数的值 那么该值的改变只在本对象中修改 其他对象保持原来不变 在本例子中 p1.likes2.append(‘游泳’) 就是这个道理
_ slots_ 限制属性的作用
- _ slots_ 是一个限制属性
如: _ slots_ =(‘price’,)
这个的意思是 限制能够使用的属性 比如 这里写了一个元组 元组内有’price’ 那么在后面就只能使用price 这个参数 而size 和color 等参数就不能使用和调用 - 一般来说 如果是自己写这个程序 这个项目 一般不使用这样的操作
构造函数以及析构函数
class Ipad:
# 限制属性
# __slots__ = ('price',)
# 这个的意思是 限制能够使用的属性 比如 这里写了一个元组 元组内有'price'
# 所以在后面就只能使用price 而size 和color 使用就会直接报错
# 构造函数
def __init__(self,price,size,color): # 有几个属性就一般写几个形参
self.price = price
self.size = size
self.color = color
# 析构函数 [了解即可 很多语言析构函数是用来释放内存的 由于python有自动回收机制 所以析构函数仅了解即可]
def __del__(self):
print('析构函数调用了')
# 创建对象
ipad_mini = Ipad(3000,9.7,'土豪金')
print(ipad_mini.price,ipad_mini.size,ipad_mini.color) # 3000 9.7 土豪金
# 这里就自带retrun了
# 尽量在后面写代码的时候将属性写在对象属性内
del ipad_mini
print('end')
#
'''
3000 9.7 土豪金
析构函数调用了
end
''' # 这就说明了 析构函数的调用是在class的函数结束之前就执行了 所以end在’析构函数被调用了‘ 之后才打印
构造函数/初始化函数
1. 在对象创造时自动被调用
2. 在这个函数中可以初始化属性
析构函数
在对象销毁时 会自动调用
在这个例子中‘end’的打印在‘析构函数调用了’之后可以充分说明 析构函数的调用在class 调用结束的时候执行了 而end在class调用之后才能打印 所以打印在了‘解析函数调用了’ 之后