01类和对象以及继承多态
面向对象特点:封装、继承、多态
1.类和对象概念
与java一致
2.类定义与访问
class 类名([父类列表]):
"""类注释"""
类体
一个类由5部分构成:class关键字。类名称,继承父类列表,类的文档字符串和类体组成。类体主要由属性和方法构成(python支持函数重载但不支持方法重载)
方法:类对某一类事物的抽象,如果需要给一个类添加功能,需要在类中定义方法来实现,方法就是类中定义的函数,如鱼类都具有有用的功能
class fish(object):
def __init__(self): #构造函数
name = "小金鱼" #属性,name = ""定义了公有属性name,__name = "",表示私有属性
age = 1 #属性
def swim(self):
print("游泳")
def breath(self):
print("呼吸")
fish1 = fish() #生成一个对象
fish1.swim()
如果,属性已经确定只有name,age,不允许中途通过其他函数self.score = 10 形式给类中添加新属性score
class people():
def __init__(self, name, age): # 构造函数->生成对象时调用
print("__init__")
self.name = name;#--公有属性
self.age = age;
# self.__name = name; 私有属性
# def __new__(cls, name, age):#new 返回 类对象,不常用
# print("__new__")
# cls.name = name
# cls.age = age
def eat(self): # 定义公有eat方法;def __eat(self):定义私有方法
print(self.name, '吃饭')
def sleep(self):
print(self.name, "睡觉")
def __del__(self):#析构函数->释放内存
print(self.name,"当前对象内存被释放了")
p1 = people("zs", 10)
p2 = people("lisi",20)
p1.sleep()
p2.sleep()
python中很少有私有属性
3.继承特性
方法不能重载,但可以重写
class father:
def __init__(self,name):
print("father构造")
self.name = name
def swim(self):
print(self.name,"游泳")
class mother:
def __init__(self,name):
print("mother构造")
self.name = name
def run(self):
print(self.name,"跑步")
class son(father,mother): #多继承,如果多个父类,存在相同的方法,默认使用从左到右进行使用
pass
class girl(father):
pass
class duck:
def swim(self):
print("鸭子游泳")
def fun(father): #father是变量名
father.swim()
s = son("son")
g = girl("girl")
d = duck()
# fun(s)
# fun(g)
fun(d)
继承的二义性问题:
当一个子类继承多个父类时,若多个父类中存在相同的方法,子类的调用规则时,从左往右深度优先原则进行
4.多态特性
静态语言与动态语言
5.获取对象信息
1)使用type查看指定对象的类型信息
2)对继承关系来说,使用type()则不方便,需要判断class的类型,可以使用isinstance()函数
3)dir函数
如果要获得一个对象的所有属性和方法,可以使用dir()函数,返回一个包含字符串的list
练习
不用加法和乘法实现列表的拼接和重复
class mylist: #提供[1,2]*3->[1,2,1,2,1,2]
def __init__(self,listName):
self.listName = listName;
def __add__(self, other):
print("调用了加号操作")
self.listName.extend(other.listName)
def __mul__(self, other): #
print("调用了乘法操作")
tmp = self.listName.copy() #[1,2]
for x in range(other-1):
self.listName.extend(tmp)
def __eq__(self,other):
#判断两个列表值是都是一样的,my1 == my2->调用__eq__
my1 = mylist([1,2])
my2 = mylist([3,4])
my1+my2 #->[1,2,3,4]
print(my1.listName)
my1*3
print(my1.listName)
02 异常操作
1.python异常继承结构
BaseException:所有内置异常的基类,自定义异常不直接继承BaseException
子类:
SystemExit:调用sys.exit()
KeyboardInterrupt:中断键(ctrl+c del)
Exception:常见错误的基类,用户自定义的异常,只能继承Exception
2.常见异常
IndexError:索引越界
ValueError:传参问题
KeyError:主键值不存在
TypeError:类型错误
SyntaxError:语法错误
3.异常处理 try…except…else…finally…raise
try:
print(10/10)
except ZeroDivisionError as e:
print("除零异常")
else:
print("没有发生异常")
finally:
print("finally 块必定执行")
#自定义异常
class MyException(Exception):
def __init__(self):
print("自定义异常对象")
def fun(a):
if a == 1:
raise MyException()
print(10/a)
try:
fun(0)
except ZeroDivisionError as e:
print("除零异常")
except MyException as e:
print("自定义异常")
else:
print("没有发生异常")
finally:
print("必定会被执行finally块")
03 文件操作
1.打开文件-open(‘路径’,模式,编码)
编码默认使用系统编码UTF-8
f.open('test01.py',mode = 'r',encoding = 'utf-8')
f.close()
->等价于
with open('test01.py',mode = 'r',encoding = 'utf-8') as f:
文件操作事件(pass)
2.打开模式
模式 操作
r 只读
w 只写
rb 二进制读
wb 二进制写
a 追加
ab 以二进制形式追加
r+ 读写
w+ 读写
3.读取文件
f.read():一次性读出来
f.readline():一行行读取
f.readlines():全部读取出来,每一行存储成一个列表元素
4.写文件
f.open('test01.py',mode = 'w',encoding = 'utf-8')
f.write('写入内容')
模式:
w->写,若没有此文件,则创建一个文件;若有文件,则将原有内容覆盖
a->写,若没有此文件,则创建一个文件;若有文件,将新内容追加到源文件后面
x->原创模式,如果路径下存在该文件,则提示文件已存在,不允许写入新内容;若不存在,则创建文件并写入
例如:
f1 = open('test01.py',mode='r',encoding='utf-8')
f2 = open('test66.py',mode='w',encoding='utf-8')
f2.write(f1.read())
f1.close()
5.删除文件
import os
os.remove('test01.py')
6.重命名文件
import os
os.rename('修改前名','修改后名')
04多线程、网络
1.开启线程两种方式
1.1 实例化Thread
from threading import Thread
def fun(a):
print('subthread run...')
t = Thread(target=fun(10))
t.start()
1.2 继承Thread
from threading import Thread
class MyThread(Thread):
def run(self):
print('subthread run...')
my = MyThread()
my.start()
2.Thread实例对象的方法
isAlive():线程是否活动
getName():线程名
setName():设置线程名
join():使主线程阻塞,知道该线程结束
threading模块:
threading.currentThread():返回当前线程
threading.enumerate():返回一个包含正在运行的线程list
threading.activeCount():返回正在运行的线程数量
->len(threading.enumerate())
3.锁
lock = threading.Lock()
lock.acquire():获取锁
lock,release():释放锁
死锁问题:
lock = threading.Lock()
lock.acquire()
lock.acquire():程序阻塞
lock,release()
lock.release()
解决方法:递归锁(RLock)
lock = threading.RLock()
RLock:内部维护一个Lock和一个counter变量,counter变量记录acquire的次数
直到一个线程所有的acquire都被release,其他线程才能获得资源
信号量:能够并发执行的线程数,超出的线程阻塞,直到有线程运行完成
Semaphore:管理一个内置的计数器,每当调用acquire内置计数器-1
release:计数器+1,计数器不能<0,否则acquire将阻塞线程直到其他线程调用release
threading。Semaphore(5)
4.事件(event)
event.isSet():返回event状态值
event.wait():event.isSet()==False
event.set():设置状态值为True
event.clear():状态值恢复到False