一、运算符重载
- 通过在类中实现运算符对应的魔法方法,来让类的对象支持相关运算符的操作
- python中所有的数据类型都是类,数据都是对象。
- 所有的运算符对应的操作,本质都是在调用数据类型对应的魔法方法。(每个运算符都对应一个固定的魔法方法)
class Student(object):
def __init__(self, name, age=0, score=0):
self.name = name
self.age = age
self.score = score
def __repr__(self):
return str(self.__dict__)
# 重载加法预算符
# self + other = return 返回值
def __add__(self, other):
return self.age + other.age
# 重载乘法运算符
def __mul__(self, other):
return self.score * other
# >
def __gt__(self, other):
return self.score > other.score
# <
# def __lt__(self, other):
# return self.score < other.score
# 注意: >和<只需要重载一个
stu1 = Student('小明', 18, 60)
stu2 = Student('小花', 22, 80)
print(stu1 + stu2)
print(stu1 * 10)
print(stu1 > stu2)
print(stu1 < stu2)
all_students = [stu1, stu2, Student('小小', 17, 55), Student('xiaohong', 25, 70)]
all_students.sort()
print(all_students)
补充: 重载
- 函数的重载:函数名相同但是参数不同的函数可以有多个,叫做函数的重载。(但是python不支持函数的重载)
二、拷贝(面试点)
1.直接赋值
- 一个变量直接给另外一个变量赋值:直接将地址赋值,赋完后两个变量指向同一块内存区域,并且相互影响
2.拷贝原理
- 将被拷贝的对象复制一份,产生一个新的数据,然后将新的数据的地址返回
3.浅拷贝
-
列表或字典的copy方法是浅拷贝、切片也是浅拷贝
-
copy.copy(对象):复制指定的对象,产生一个新的对象(不会复制子对象)
dog1 = Dog('财财')
stu2 = Student('Lisa', 18, 60)
stu2.dog = dog1
stu4 = copy.copy(stu2)
print('stu4:', stu4)
stu2.name = '小花'
print(stu2, stu4)
4.深拷贝
-
copy.deepcopy(对象):复制指定的对象,产生一个新的对象。如果这个对象中有其他的对象,子对象也会被复制
dog1 = Dog('财财')
stu2 = Student('Lisa', 18, 60)
stu2.dog = dog1
stu4 = copy.deepcopy(stu2)
print('stu4:', stu4)
stu2.name = '小花'
print(stu2, stu4)
三、内存管理(面试点)
1. 数据的存储(内存开辟)
- python的变量都存储在栈区间,对象都在堆区间
- 声明变量或者给变量赋值,是先在内存(堆)中开辟存储数据,然后将数据地址保存在变量中
- 但是数字和字符串特殊,如果是用数字或者字符串给变量赋值,不会直接开辟空间保存数据,而是先在内存检测这个数据之前是否已经存储过,如果已经存储直接用上次保存的数据,没有存储才会开辟新的空间保存数据
2. 内存的释放
1)引用计数
- python每个对象都有一个属性叫引用计数,用来保存当前对象的引用的个数
2)垃圾回收机制
- python中的垃圾回收机制来判断一个对象是否销毁,就看这个对象的引用计数是否为零,如果为零就会被销毁
- 注意循环引用的问题(另有特殊机制去销毁)
from sys import getrefcount
list1 = [1, 2]
print(getrefcount(list1))
# def yt_getrefcount(obj):
# # obj = list1
# return 获取obj对应的数据的引用个数
# yt_getrefcount(list1)
# 让引用计数增加
list2 = list1
print(getrefcount(list1))
dict1 = {'a': list2}
print(getrefcount(list1))
#
# num = 100
# print(getrefcount(num))
# num1 = 100
# print(getrefcount(num))
# 让引用计数减少
print(getrefcount(list1))
list2 = 100
print(getrefcount(list1))
del dict1['a']
print(getrefcount(list1))
del list1
# print(getrefcount(list1))
四、套接字(socket)
- 进行通信的两端就是套接字;有两种类型,分别是服务器套接字、客户端套接字
- 导入socket模块:from socket import * 或 import socket
1. 服务器套接字(server)
1)创建套接字对象
- server = socket() 或者 server = socket(family=AF_INET, type=SOCK_STREAM)(默认参数,可省略不写)
- 参数说明:
family:设置ip协议类型, AF_INET(ipv4),AF_INET6(ipv6)
type:设置传输协议类型, SOCK_STREAM(TCP),SOCK_DGRAM(UDP)
2)绑定地址(ip地址和端口)
- server.bind(('10.7.185.82', 8080))
- 语法:bind((ip地址, 端口))
- 参数说明:
ip地址:字符串,服务器对应的ip地址
端口号:int, 端口号用来区分一台电脑上的不同的服务。范围:0-65535, 其中0-1024是著名端口,一般不选。同一时间一个端口只能绑定一个服务
3)监听请求
4)让服务器一直运行
5)接收请求
- connect, address = server.accept()
- 代码运行到这个位置,会停下来,等到有客户端给服务器发送请求为止
6)接收数据
- redata = connect.recv(1024)
- print(redata.decode(encoding='utf-8'))
- 参数说明:
recv(bufsize):bufsize,设置一次性能够接收的数据大小的最大值,单位是字节
返回的数据类型是字节
7)发送数据
- send_message = input('输入文字:')
- connect.send(send_message.encode())
8)关闭连接
实例:
from socket import *
# 1.创建套接字对象
server = socket()
# 2.绑定地址
server.bind(('10.7.185.82', 8080))
# 3.监听
server.listen(512)
# 4.让服务器一直运算
while True:
print('开始监听....')
# 5. 接受请求
connect, address = server.accept()
# 6.接收数据
redata = connect.recv(1024)
message = redata.decode(encoding='utf-8')
# 7.发送数据
if message == 'text':
# 发送文字
send_message = input('输入文字:')
connect.send(send_message.encode())
elif message == 'image':
# 发送图片
with open('server/luffy4.jpg', 'rb') as f:
image_data = f.read()
# connect.send('你好'.encode())
connect.send(('{"type":"jpg", "lengh":%d}' % len(image_data)).encode())
connect.send(image_data)
# 8.关闭连接
connect.close()
2. 客户端套接字(client)
1)创建套接字对象
2)连接服务器
- client.connect(('10.7.185.82', 8085))
3)发送数据
- message = input('请输入:')
- client.send(message.encode())
4)接收数据
- re_data = client.recv(1024)
- print(re_data.decode(encoding='utf-8'))
实例:
from socket import socket
# 1.创建套接字对象
client = socket()
# 2.连接服务器
client.connect(('10.7.185.82', 8080))
# 3.发送数据
print('1.获取文字请输入text\n2.获取图片请输入image')
send_message = input(':')
client.send(send_message.encode())
# 4.接收数据
if send_message == 'text':
text_data = client.recv(1024)
print(text_data.decode(encoding='utf-8'))
elif send_message == 'image':
image_message = client.recv(1024)
print(image_message.decode(encoding='utf-8'))
while True:
image_data = client.recv(1024)
if len(image_data) == 0:
break
with open('client/image.jpg', 'ab') as f:
f.write(image_data)
client.close()