一、運算符重載
- 通過在類中實現運算符對應的魔法方法,來讓類的對象支持相關運算符的操作
- 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()