20-Python拷贝、内存管理和网络通信

本文探讨Python中的拷贝机制,包括直接赋值、浅拷贝和深拷贝,解释了它们的区别。同时,文章也涉及内存管理,阐述了Python如何自动化管理内存,以及垃圾回收的过程。最后,简要介绍了服务端Server和客户端Client的通信。
摘要由CSDN通过智能技术生成

1.拷贝、浅复制和深复制

from copy import copy, deepcopy
class Dog:
    def __init__(self, name, color='黑色'):
        self.name = name
        self.color = color

class Person:
    def __init__(self, name, age=0, gender='女'):
        self.name = name
        self.age = age
        self.gender = gender
        self.dog = None

    def __repr__(self):
        return f'<{str(self.__dict__)[1:-1]}, id:{id(self)}>'


p1 = Person('小明')
print(p1) # <'name': '小明', 'age': 0, 'gender': '女', 'dog': None, id:35399624>

1.1 直接赋值

p2 = p1
print(p2) # <'name': '小明', 'age': 0, 'gender': '女', 'dog': None, id:32036936>
p2.name = '小花'
print(p2) # <'name': '小花', 'age': 0, 'gender': '女', 'dog': None, id:32036936>
print(p1) # <'name': '小花', 'age': 0, 'gender': '女', 'dog': None, id:32036936>

1.2 拷贝

不管怎么拷贝,都是复制原数据产生一个新的数据并且将新数据的地址返回

p1 = Person('小明')
print('p1:', p1) # p1: <'name': '小明', 'age': 0, 'gender': '女', 'dog': None, id:35314312>
p3 = copy(p1)
p4 = deepcopy(p1)
print('p3:', p3) # p3: <'name': '小明', 'age': 0, 'gender': '女', 'dog': None, id:35320904>
print('p4:', p4) # p4: <'name': '小明', 'age': 0, 'gender': '女', 'dog': None, id:35321096>

1.3 浅拷贝和深拷贝的区别

总结:

  • **直接赋值:**其实就是对象的引用(别名)。
    在这里插入图片描述

  • **浅拷贝(copy):**拷贝父对象,不会拷贝对象的内部的子对象。
    在这里插入图片描述

  • 深拷贝(deepcopy): copy 模块的 deepcopy 方法,完全拷贝了父对象及其子对象。
    在这里插入图片描述

1. 浅拷贝

copy模块里面的copy方法实现。浅拷贝后,改变原始对象中为可变类型的元素的值,会同时影响拷贝对象;改变原始对象中为不可变类型的元素的值,不会响拷贝对象。

2. 深拷贝

copy模块里面的deepcopy方法实现。深拷贝,除了顶层拷贝,还对子元素也进行了拷贝。经过深拷贝后,原始对象和拷贝对象所有的可变元素地址都没有相同的了。

print('=================浅拷贝=================')
p1 = Person('Tom', 18, '男')
p1.dog = Dog('大黄', '黄色')
print('p1:', p1) # p1: <'name': 'Tom', 'age': 18, 'gender': '男', 'dog': <__main__.Dog object at 0x00000000021DDD08>, id:35518152>

# 浅拷贝
p2 = copy(p1)
print('p2:', p2) # p2: <'name': 'Tom', 'age': 18, 'gender': '男', 'dog': <__main__.Dog object at 0x00000000021DDD08>, id:35683208>
p2.dog.color = '绿色' 
print(p1.dog.color) # 绿色


print('================深拷贝====================')
p1 = Person('Tom', 18, '男')
p1.dog = Dog('大黄', '黄色')
print('p1:', p1) # p1: <'name': 'Tom', 'age': 18, 'gender': '男', 'dog': <__main__.Dog object at 0x00000000027E27C8>, id:41917640>
# 深拷贝
p2 = deepcopy(p1)
print('p2:', p2) # p2: <'name': 'Tom', 'age': 18, 'gender': '男', 'dog': <__main__.Dog object at 0x0000000002806C88>, id:41970376>
p2.dog.color = '绿色'
print(p1.dog.color) # 黄色

2.内存管理

  1. 内存管理:

    python内存管理是自动化(指的是对堆上的内存进行管理)

  2. 内存的开辟

只要需要保存数据的时候系统就会自动在堆上开辟内存空间保存数据。

注意:如果需要被保存的数据是数字或者字符串,系统会先检查专门保存数字字符串的的缓存区中是否已经存在这

个数据,如果存在直接返回之前的数据的地址,不存在才会开辟新的内存去保存。(短小数字和字符串)

str1 = 'abc'
list1 = ['abc', 10, 20]
print(id(str1), id(list1[0]))   # 4468066352 4468066352

list2 = []
list3 = []
print(id(list2), id(list3))   # 4467411936 4468530144

num1 = -6
num2 = -6
print(id(-6), id(-6)) # 31630224 31630224
  1. 内存的释放(垃圾回收)

Python中的每一个数据都有一个属性用来保存这个数据的引用个数(引用计数),当引用计数的值为0,那么这个数据就会自动销毁。实际上会有短暂的延迟,人感觉不到。

3.服务端Server

# 1.socket
# socket又叫套接字(实现通信的两个端(程序)就是套接字)
# 套接字有两种:服务器套接字(server)、客户端套接字(client)

# 2.服务器套接字
# 1)创建socket对象(买电话机)
from socket import socket
"""
socket(family=AF_INET, type=SOCK_STREAM)   -  创建一个套接字对象

family  -  IP的类型(ipv4, ipv6);
           AF_INET == ipv4 (默认的)
           AF_INET6 == ipv6
type  -   传输类型(TCP、UDP)
          SOCK_STREAM  == TCP (默认)
          SOCK_DGRAM  == UDP
"""

server = socket()

# 2)绑定ip和端口(插电话线)

"""
套接字对象.bind((ip地址,端口))
ip地址  -  找到到服务器对应的计算机;字符串
端口  - 区分计算机中不同的服务(服务指的是正在运行的程序); 整数,范围是0~65535(其中0~1023属于著名端口)
"""

server.bind(('10.7.184.61', 8082))

# 3)开始监听(等待别人打电话)

"""
服务器套接字对象.listen(数量)    -  数量决定了同一时间的最大通信数(能处理的客服端最大数量)
"""

server.listen(512)

# 4)让服务器一直运行
while True:
    print('等待电话...')
    # 1)接受客户端的请求(接电话)
    connect, address = server.accept()
    print('通话...')
    # 2)接受消息
    # recv(字节数)  - 接受数据(字节数-一次能接受的最大的数据)
    re_data = connect.recv(1024)
    print(f'接受数据:{address[0]}')
    print(str(re_data, encoding='utf-8'))

    # 3)发送消息
    # with open('index.html', 'r', encoding='utf-8') as f:
    #     message = f.read()
    # connect.send(bytes('HTTP/1.1 200 OK\r\n\r\n '+message, encoding='utf-8'))
    
    connect.send('吃了!'.encode())

4.客户端Client

# 1.创建套接字对象
from socket import socket
client = socket()

# 2.连接服务器(拨号,打电话)
client.connect(('10.7.184.61', 8082))

while True:
    # 3.发送消息
    # 字符串.encode() - 将转换成二进制数据
    message = input('>>>:')
    client.send(message.encode(encoding='utf-8'))

    # 4.接受消息
    # 二进制数据.decode() - 将二进制数00
    re_data = client.recv(1024)
    print(re_data.decode(encoding='utf-8'))

5.Server持续通信

from socket import socket
server = socket()
server.bind(('10.7.184.61', 8082))
server.listen(512)
\# 让服务器一直运行
while True:
    print('等待...')
    connect, address = server.accept()

    # 建立连接后可以一直通话
    while True:
        re_data = connect.recv(1024)
        print(f'{address[0]}:{re_data.decode()}')
        if re_data.decode() == '拜拜':
            break
    
        message = input('>>>')
        connect.send(message.encode())
        if message == '拜拜':
            break

print(f’{address[0]}:{re_data.decode()}’)
if re_data.decode() == ‘拜拜’:
break

    message = input('>>>')
    connect.send(message.encode())
    if message == '拜拜':
        break
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值