一硕蛹、運算符重載
- 通過在類中實現(xiàn)運算符對應(yīng)的魔法方法,來讓類的對象支持相關(guān)運算符的操作
- python中所有的數(shù)據(jù)類型都是類硕并,數(shù)據(jù)都是對象法焰。
- 所有的運算符對應(yīng)的操作,本質(zhì)都是在調(diào)用數(shù)據(jù)類型對應(yīng)的魔法方法倔毙。(每個運算符都對應(yīng)一個固定的魔法方法)
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__)
# 重載加法預(yù)算符
# 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)
補充: 重載
- 函數(shù)的重載:函數(shù)名相同但是參數(shù)不同的函數(shù)可以有多個埃仪,叫做函數(shù)的重載。(但是python不支持函數(shù)的重載)
二陕赃、拷貝(面試點)
1.直接賦值
- 一個變量直接給另外一個變量賦值:直接將地址賦值卵蛉,賦完后兩個變量指向同一塊內(nèi)存區(qū)域,并且相互影響
2.拷貝原理
- 將被拷貝的對象復(fù)制一份么库,產(chǎn)生一個新的數(shù)據(jù)傻丝,然后將新的數(shù)據(jù)的地址返回
3.淺拷貝
-
列表或字典的copy方法是淺拷貝、切片也是淺拷貝
-
copy.copy(對象):復(fù)制指定的對象诉儒,產(chǎn)生一個新的對象(不會復(fù)制子對象)
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(對象):復(fù)制指定的對象葡缰,產(chǎn)生一個新的對象。如果這個對象中有其他的對象忱反,子對象也會被復(fù)制
dog1 = Dog('財財')
stu2 = Student('Lisa', 18, 60)
stu2.dog = dog1
stu4 = copy.deepcopy(stu2)
print('stu4:', stu4)
stu2.name = '小花'
print(stu2, stu4)
三泛释、內(nèi)存管理(面試點)
1. 數(shù)據(jù)的存儲(內(nèi)存開辟)
- python的變量都存儲在棧區(qū)間,對象都在堆區(qū)間
- 聲明變量或者給變量賦值缭受,是先在內(nèi)存(堆)中開辟存儲數(shù)據(jù),然后將數(shù)據(jù)地址保存在變量中
- 但是數(shù)字和字符串特殊该互,如果是用數(shù)字或者字符串給變量賦值米者,不會直接開辟空間保存數(shù)據(jù),而是先在內(nèi)存檢測這個數(shù)據(jù)之前是否已經(jīng)存儲過,如果已經(jīng)存儲直接用上次保存的數(shù)據(jù)蔓搞,沒有存儲才會開辟新的空間保存數(shù)據(jù)
2. 內(nèi)存的釋放
1)引用計數(shù)
- python每個對象都有一個屬性叫引用計數(shù)胰丁,用來保存當(dāng)前對象的引用的個數(shù)
2)垃圾回收機制
- python中的垃圾回收機制來判斷一個對象是否銷毀,就看這個對象的引用計數(shù)是否為零喂分,如果為零就會被銷毀
- 注意循環(huán)引用的問題(另有特殊機制去銷毀)
from sys import getrefcount
list1 = [1, 2]
print(getrefcount(list1))
# def yt_getrefcount(obj):
# # obj = list1
# return 獲取obj對應(yīng)的數(shù)據(jù)的引用個數(shù)
# yt_getrefcount(list1)
# 讓引用計數(shù)增加
list2 = list1
print(getrefcount(list1))
dict1 = {'a': list2}
print(getrefcount(list1))
#
# num = 100
# print(getrefcount(num))
# num1 = 100
# print(getrefcount(num))
# 讓引用計數(shù)減少
print(getrefcount(list1))
list2 = 100
print(getrefcount(list1))
del dict1['a']
print(getrefcount(list1))
del list1
# print(getrefcount(list1))
四锦庸、套接字(socket)
- 進(jìn)行通信的兩端就是套接字;有兩種類型蒲祈,分別是服務(wù)器套接字甘萧、客戶端套接字
- 導(dǎo)入socket模塊:from socket import * 或 import socket
1. 服務(wù)器套接字(server)
1)創(chuàng)建套接字對象
- server = socket() 或者 server = socket(family=AF_INET, type=SOCK_STREAM)(默認(rèn)參數(shù),可省略不寫)
- 參數(shù)說明:
family:設(shè)置ip協(xié)議類型, AF_INET(ipv4)梆掸,AF_INET6(ipv6)
type:設(shè)置傳輸協(xié)議類型, SOCK_STREAM(TCP)扬卷,SOCK_DGRAM(UDP)
2)綁定地址(ip地址和端口)
- server.bind(('10.7.185.82', 8080))
- 語法:bind((ip地址, 端口))
- 參數(shù)說明:
ip地址:字符串,服務(wù)器對應(yīng)的ip地址
端口號:int, 端口號用來區(qū)分一臺電腦上的不同的服務(wù)酸钦。范圍:0-65535, 其中0-1024是著名端口怪得,一般不選。同一時間一個端口只能綁定一個服務(wù)
3)監(jiān)聽請求
4)讓服務(wù)器一直運行
5)接收請求
- connect, address = server.accept()
- 代碼運行到這個位置卑硫,會停下來徒恋,等到有客戶端給服務(wù)器發(fā)送請求為止
6)接收數(shù)據(jù)
- redata = connect.recv(1024)
- print(redata.decode(encoding='utf-8'))
- 參數(shù)說明:
recv(bufsize):bufsize,設(shè)置一次性能夠接收的數(shù)據(jù)大小的最大值,單位是字節(jié)
返回的數(shù)據(jù)類型是字節(jié)
7)發(fā)送數(shù)據(jù)
- send_message = input('輸入文字:')
- connect.send(send_message.encode())
8)關(guān)閉連接
實例:
from socket import *
# 1.創(chuàng)建套接字對象
server = socket()
# 2.綁定地址
server.bind(('10.7.185.82', 8080))
# 3.監(jiān)聽
server.listen(512)
# 4.讓服務(wù)器一直運算
while True:
print('開始監(jiān)聽....')
# 5. 接受請求
connect, address = server.accept()
# 6.接收數(shù)據(jù)
redata = connect.recv(1024)
message = redata.decode(encoding='utf-8')
# 7.發(fā)送數(shù)據(jù)
if message == 'text':
# 發(fā)送文字
send_message = input('輸入文字:')
connect.send(send_message.encode())
elif message == 'image':
# 發(fā)送圖片
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.關(guān)閉連接
connect.close()
2. 客戶端套接字(client)
1)創(chuàng)建套接字對象
2)連接服務(wù)器
- client.connect(('10.7.185.82', 8085))
3)發(fā)送數(shù)據(jù)
- message = input('請輸入:')
- client.send(message.encode())
4)接收數(shù)據(jù)
- re_data = client.recv(1024)
- print(re_data.decode(encoding='utf-8'))
實例:
from socket import socket
# 1.創(chuàng)建套接字對象
client = socket()
# 2.連接服務(wù)器
client.connect(('10.7.185.82', 8080))
# 3.發(fā)送數(shù)據(jù)
print('1.獲取文字請輸入text\n2.獲取圖片請輸入image')
send_message = input(':')
client.send(send_message.encode())
# 4.接收數(shù)據(jù)
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()