1.类和实例
类:公共的属性(相对静态)和行为,共性,一般
实例:是类的一个具体实现,个性,特殊
类:用来描述具有相同的属性和方法的对象的集合,它定义了该集合中每个对象所共有的属性和方法,对象是类的实例
2.类的定义
类的定义使用关键字class语法如下:
class 类的名字(上级类,可省略):
a=1 #类的属性
def __init__(self,name):
self.name=name #实例的属性
def print_name(self):
print(self.name)
#类的基本概念
#类的定义
class Student():
count=0 #类的属性
def __init__(self,name):
self.name=name #实例的属性
count=self.count+1
def print_name(self): #方法
print(self.name)
#生成实例,调用类定义中的__init__方法
s1=Student("张三")
s2=Student("李四")
#输出实例的属性
print(s1.name,s1.count)
print(s2.name,s2.count)
#使用类的方法
s1.print_name()
s2.print_name()
#输出类的属性
print(Student.count)
执行结果如下:
3.类方法的写法
类方法写法和函数定义类似,不同之处是有一个额外的参数self,self值指的是实例自身,使用实例调用方法的时候不用写这个参数在类方法中可以使用实例属性和类属性,实例属性只有实例才能用,类属性都能用类的方法只有类的实例可以使用
4.类属性与实例属性
假如student是一个类,定义了一个类属性a和实例属性b(self.b)。定义了一个类方法f 。在使用时,生成了两个实例s1和s2。实例可以使用类属性和实例属性:s1.a 、s1.b、 s2.a、 s2.b实例可以使用类方法s1.f()、s2.f()类可以使用类属性,不能使用实例属性student.a。
#类的基本概念
#类的定义
class Student():
count=0 #类的属性
def __init__(self,name):
self.name=name #实例的属性
#count=self.count+1
Student.count+=1
def print_name(self): #方法
print(self.name)
print(Student.count)
#生成实例,调用类定义中的__init__方法
s1=Student("张三")
s2=Student("李四")
#输出实例的属性
print(s1.name,s1.count)
print(s2.name,s2.count)
#使用类的方法
s1.print_name()
s2.print_name()
#输出类的属性
print(Student.count)
print(s1.count)
执行结果如下:
5.封装特性
#封装,告诉你能知道的,隐藏你不该知道的
class Student():
def __init__(self,name,money):
self.name=name #实例的属性
self.__money=money #两个下划线开头的叫隐藏属性,只有类内部能使用。
def print_info(self): #方法
print(self.name)
if self.__money>1000:
print("这是一个有钱人!")
else:
print("这是一个穷光蛋!")
def __test(self):
print("试试看")
def test(self):
self.__test()
s1=Student("张三",800)
s2=Student("李四",100000)
s1.print_info()
s2.print_info()
print(s1.name)
s1.test()
#s2.__test()
执行结果如下:
__xx__的叫隐藏属性,只有内部可以使用
6.继承特性
#继承,类是有层次的,上级定义好的下级类可以直接拿来用
class People():
i=1
def __init__(self,name,age,weight):
self.name=name
self.age=age
self.__weight=weight
def speak(self):
if self.__weight>100:
print(f"我叫{self.name},今年{self.age}岁,我有点胖!")
else:
print(f"我叫{self.name},今年{self.age}岁,我一点也不胖!")
class Student(People):
def __init__(self,name,age,weight,grade):
People.__init__(self,name,age,weight)
self.grade=grade
def print_inf(self):
print(f"我叫{self.name},今年{self.age}岁,我{self.grade}年级了。")
p1=People("张三",18,101)
s1=Student("李四",16,88,3)
p1.speak()
s1.speak() #父类的方法子类也能用
s1.print_inf()
print(s1.i)
print(Student.i)
执行结果如下:
如上图student类可以用可以嵌入上面的people类,如果多继承,在前面的优先级高,遇到重名的选择前面的。
7. 多态特性
#多态,继承自同一个父类的子类可以有不同的实现
class Funs():
def __init__(self,name):
self.name=name
def watch(self):
print("有空就看直播!")
def __str__(self): #把对象转换为字符串输出
return f"粉丝{self.name}"
def __len__(self):
return len(self.name)
class tuhao(Funs):
def watch(self): #子类可以重新写父类的方法
print(f"{self.name}一看直播就刷火箭!")
class qren(Funs):
def watch(self):
print(f"{self.name}光看直播不送礼物!")
xiaoming=tuhao("王小明")
xiaojun=qren("李小军")
def kanzhibo(fan):
fan.watch()
funs=[xiaoming,xiaojun]
for i in funs:
print(i)
#print(isinstance(i,Funs))
#print(isinstance(i,tuhao))
print(len(i))
kanzhibo(i)
执行结果如下:
8.获取对象信息
获取对象信息需要加上isinstance
type函数可以用来判断基本类型
9.方法重载
重载方法格式:
def __xxx__(self,other):
...
注:重载方法格式
-----------------------------------------------------------------运算符
运算符重载:
作用:
让自定义的类创建的对象像内建对象一样进项运算符操作
算数运算符:
__add__ 加法 +
__sub__ 减法 -
__mul__ 乘法 *
__truedif__ 除法 /
__floordiv__ 地板除 //
__mod__ 取模(求余) %
__pow__ 幂 **
反向算数运算符重载:
__radd__(self, lhs) # 加法 lhs + self
__rsub__(self, lhs) # 减法 lhs + self
__rmul__(self, lhs) # 乘法 lhs * self
__rtruediv__(self, lhs) # 除法 lhs / self
__rfloordiv__(self, lhs) # 地板除 lhs // self
__rmod__(self, lhs) # 取模 lhs % self
__rpow__(self, lhs) # 幂运算 lhs ** self
注:lhs(left hand side) 左手边
复合赋值算数运算符的重载:
__iadd__(self, other) # 加法 self += other
__isub__(self, other) # 减法 self -= other
__imul__(self, other) # 乘法 self *= other
__itruediv__(self, other) # 除法 self /= other
__ifloordiv__(self, other) # 地板除 self //= other
__imod__(self, other) # 取模 self %= other
__ipow__(self, other) # 幂运算 self **= other
注:当重载后优先使用重载的方法,否则使用__add__等方法代替
-----------------------------------------------------------------比较运算符
比较运算符重载:
__lt__ 小于 <
__le__ 大于等于 <=
__gt__ 大于 >
__ge__ 大于等于 >=
__eq__ 等于 ==
__ne__ 不等于 !=
-----------------------------------------------------------------位操作运算符
位操作运算符重载:
__and__ 位与 &
__or__ 位或 |
__xor__ 位异或 ^
__lshift__ 左移 <<
__rshift__ 右移 >>
反向位操作运算符:
__rand__ 位与 &
__ror__ 位或 |
__rxor__ 位异或 ^
__rlshift__ 左移 <<
__rrshift__ 右移 >>
复合赋值位运算符重载:
__iand__ 位与 &
__ior__ 位或 |
__ixor__ 位异或 ^
__ilshift__ 左移 <<
__irshift__ 右移 >>
-----------------------------------------------------------------一元运算符
一元运算符的重载:
__neg__ 符号 -
__pos__ 正号 +
__invert__ 取反 ~
重载格式:
def __xxx__(self):
pass
-----------------------------------------------------------------内建函数
内建函数重载:
def __abs__(self) abs(obj) 函数调用
def __len__(self) len(obj) 函数调用
def __reversed__(self) reversed(obj) 函数调用
def __round__(self) round(obj) 函数调用
-----------------------------------------------------------------数值转换函数
数值转换函数重载:
__int__ int(obj)
__float__ float(obj)
__complex__ complex(obj)
__bool__ bool(obj)
-----------------------------------------------------------------布尔测试运算符
布尔测试运算符重载:
格式:
def __bool__(self):
....
作用:
1) 用于bool(obj) 函数取值
2) 用于if语句真值表达式中
3) 用于while语句真值表达式中
重载说明:
当没有 __bool__(self) 方法时,真值测试将取
__len__(self) 方法的返回值来测试布尔值
-----------------------------------------------------------------in / not in
in / not in 运算符重载:
格式:
def __contains__(self, e):
...
作用:
成员资格测试(通常)
-----------------------------------------------------------------索引和切片
索引和切片运算符的重载:
重载方法:
__getitem__(self, i) 方法
__sefitem__(self, i, v) 方法
__delitem__(self, i) 方法
作用:
让自定义类型的对象能进行索引和切片操作
切片(slice)重载:
切片重载同性索引重载公用的方法
__getitem__(self, i) 切片取值
__sefitem__(self, i, v) 切片赋值
__delitem__(self, i) del切片删除
-----------------------------------------------------------------迭代器重载
迭代器:
__next__(self):
可迭代对象:
__iter__(self):
-----------------------------------------------------------------with环境管理器类内重载
类内有__enter__ 和 __exit__ 方法的类被称为环境管理器
能够用with进行管理的对象必须是环境管理器
__enter__ 方法将在进入 with 语句时被调用返回由 as 变量管理的对象
__exit__ 方法将在离开with语句时被调用,且可以用参数来判断离开with语句时是否有异常发生并作出相应的处理
10.火车票查询
#查询车票,面向对象版
import requests
from requests.packages.urllib3.exceptions import InsecureRequestWarning
# 禁用安全请求警告
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
class Station():
def __init__(self,id,cn,jp,qp):
self.id=id
self.cn=cn
self.jp=jp
self.qp=qp
url="https://kyfw.12306.cn/otn/resources/js/framework/station_name.js?station_version=1.9108"
try:
inf=requests.get(url).text
except:
print("网络有问题!")
exit()
rlist=inf[:-2].split("@")[1:]
result=[]
for i in rlist:
ilist=i.split("|")
id=ilist[2]
cn=ilist[1]
jp=ilist[0]
qp=ilist[3]
result.append(Station(id,cn,jp,qp))
def getid(station):
for i in result:
if i.cn==station or i.qp==station:
return i.id
def getcn(station):
for i in result:
if i.cn==station or i.qp==station:
return i.cn
class Ticket():
def __init__(self,fs,ts,fd,checi,ft,tt,ztype):
self.from_station=fs
self.to_station=ts
self.from_date=fd
self.checi=checi
self.from_time=ft
self.to_time=tt
self.ztype=ztype
def __str__(self):
return f"车次:{self.checi:10s} 出发时间:{self.from_time:10s} 到达时间:{self.to_time:10s} 座位类型:{self.ztype}"
from_station=input("出发站:")
to_station=input("到达站:")
from_date=input("出发日期(2019-07-01):")
fid = getid(from_station)
tid = getid(to_station)
qurl=f"https://kyfw.12306.cn/otn/leftTicket/query?leftTicketDTO.train_date={from_date}&leftTicketDTO.from_station={fid}&leftTicketDTO.to_station={tid}&purpose_codes=ADULT"
rdata=requests.get(qurl,verify=False).json()["data"]["result"]
tickets=[]
for i in rdata:
ilist=i.split("|")
checi=ilist[3]
if checi[0] in "GD":
ftime=ilist[8]
ttime=ilist[9]
zuo2=ilist[30]
if zuo2=="有" or zuo2.isdigit():
tickets.append(Ticket(getcn(from_station),getcn(to_station),from_date,checi,ftime,ttime,"二等座"))
zuo1=ilist[31]
if zuo1=="有" or zuo1.isdigit():
tickets.append(Ticket(getcn(from_station),getcn(to_station),from_date,checi,ftime,ttime,"一等座"))
vip=ilist[32]
print(f"车次:{checi} 发车时间:{ftime} 到达时间:{ttime}")
print(f" 二等座:{zuo2} 一等座:{zuo1} 商务座:{vip}")
执行结果如下:
用面向对象更加灵活。
11.键盘记录
from pynput import keyboard
def on_press(key):
try:
print('alphanumeric key {0} pressed'.format(
key.char))
except AttributeError:
print('special key {0} pressed'.format(
key))
def on_release(key):
print('{0} released'.format(
key))
if key == keyboard.Key.esc:
# Stop listener
return False
# Collect events until released
with keyboard.Listener(
on_press=on_press,
on_release=on_release) as listener:
listener.join()
# ...or, in a non-blocking fashion:
listener = mouse.Listener(
on_press=on_press,
on_release=on_release)
listener.start()
下载pynput
执行结果如下: