operator
- 什么是運(yùn)算符重載
python中所有的類型都是類,所有的數(shù)據(jù)都是類的對(duì)象
Python中使用運(yùn)算符的時(shí)候,實(shí)質(zhì)會(huì)去調(diào)用這個(gè)運(yùn)算符對(duì)應(yīng)的魔法方法。類的對(duì)象是否支持相應(yīng)的運(yùn)算符,就看這個(gè)類有沒有實(shí)現(xiàn)對(duì)應(yīng)的
魔法方法
import copy
class Student:
def __init__(self, name, age=0, score=0):
self.name = name
self.age = age
self.score = score
# __add__是+的魔法方法,self代表+前面的數(shù)據(jù),other代表+后面的數(shù)據(jù),返回值是運(yùn)算結(jié)果
def __add__(self, other):
return self.age + other.age
#注意:>和<魔法方法只需要實(shí)現(xiàn)一個(gè),另外一個(gè)自動(dòng)實(shí)現(xiàn)
def __gt__(self, other):
return self.score > other.score
def __repr__(self):
return str(self.__dict__)
stu1 = Student('小明', 20, 80)
stu2 = Student('小紅', 21, 90)
print('兩個(gè)學(xué)生相加', stu1 + stu2)
print(stu1 > stu2)
list1 = [stu1, stu2]
list1.sort()
print(list1)
內(nèi)存管理機(jī)制
內(nèi)存可以分為棧區(qū)間和堆區(qū)間,棧上的內(nèi)存是系統(tǒng)自動(dòng)開辟自動(dòng)釋放的,堆上的內(nèi)存需要手動(dòng)開辟,手動(dòng)釋放。
在Python中,堆上的內(nèi)存空間會(huì)通過Python提供的內(nèi)存管理機(jī)制自動(dòng)管理內(nèi)存管理機(jī)制
1)內(nèi)存的開辟
Python中所有的變量都是保存在棧區(qū)間的,并且所有的變量保存的都是地址;所有的對(duì)象(數(shù)據(jù))都是保存在堆區(qū)間的。
變量賦值的原理:先在堆區(qū)間開辟空間將數(shù)據(jù)存起來,然后將地址返回給變量(通用)。如果數(shù)據(jù)是數(shù)字或字符串,會(huì)先在內(nèi)存中查
看之前是否已經(jīng)存儲(chǔ)過這個(gè)數(shù)據(jù),如果存儲(chǔ)過直接返回之前的地址,沒有存儲(chǔ)過才會(huì)開辟空間存數(shù)據(jù)。
2)內(nèi)存的釋放(垃圾回收機(jī)制)
Python中的每個(gè)對(duì)象都有一個(gè)默認(rèn)的屬性來保存這個(gè)對(duì)象的引用計(jì)數(shù)。
(看這個(gè)對(duì)象的地址被多少個(gè)變量或者數(shù)據(jù)存儲(chǔ);如果一個(gè)變量存了一個(gè)對(duì)象的地址,我們就說這個(gè)變量是這個(gè)對(duì)象的引用)
一個(gè)對(duì)象是否銷毀就看這個(gè)對(duì)象的引用計(jì)數(shù)是否為0,只要為0就會(huì)被銷毀
getrefcount(對(duì)象) - 獲取對(duì)象的引用計(jì)數(shù)
from sys import getrefcount
def main():
# 1.變量賦值原理
list1 = {'a': 10}
list2 = {'a': 10}
print(id(list1), id(list2))
num1 = 'abc'
num2 = 'abc'
print(id(num1), id(num2))
# 2.引用計(jì)數(shù)
list3 = [1, 2, 3]
list4 = list3
print(getrefcount(list3), getrefcount(list4))
list4 = 10
print(getrefcount(list3))
list3 = 100
print(getrefcount(list3))
# def yt_getcount(obj):
# # obj = list3
# return 獲取obj的引用計(jì)數(shù)