day16总结:运算符重载、拷贝、内存管理和套接字(2019-05-07)

一、运算符重载

  • 通过在类中实现运算符对应的魔法方法,来让类的对象支持相关运算符的操作
  • 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)监听请求
  • server.listen(512)
4)让服务器一直运行
  • while True:
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)关闭连接
  • connect.close()
实例:
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)创建套接字对象
  • client = socket()
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()
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容