
1 重載運(yùn)算符
python中所有的數(shù)據(jù)類(lèi)型都是類(lèi),數(shù)據(jù)都是對(duì)象;所有的運(yùn)算符對(duì)應(yīng)的操作,本質(zhì)都是在調(diào)用數(shù)據(jù)類(lèi)型對(duì)應(yīng)的魔法方法,每個(gè)運(yùn)算符都對(duì)應(yīng)一個(gè)固定的魔法方法。
class Student(object):
def __init__(self, name, age=0, score=0):
self.name = name
self.age = age
self.score = score
def __add__(self, other):
return self.age + other.age
def __gt__(self, other):
return self.score > other.score
# 比較相同屬性時(shí),>和<只需要重載一個(gè)
stu1 = Student('小明', 18, 60)
stu2 = Student('小花', 22, 80)
print(stu1 + stu2)
print(stu1 > stu2)
# 練習(xí)讓student的對(duì)象支持乘法運(yùn)算,運(yùn)算規(guī)則是:
# <name:張三,age:10,score:0> * 3 = [<name:張三,age:10,score:0>,<name:張三,age:10,score:0>,<name:張三,age:10,score:0>]
class Student(object):
def __init__(self, name='張三', age=10, score=0):
self.name = name
self.age = age
self.score = score
def __repr__(self):
return '<' + str(self.__dict__)[1:-1] + '>'
def __mul__(self, other):
list1 = []
for i in range(other):
list1.append(self)
return list1
s1 = Student()
result = s1 * 3
print(result)
s1.name = '小明'
print(result) # 改變屬性后,列表內(nèi)容隨之改變
2、深拷貝和淺拷貝
一個(gè)變量直接給另一個(gè)變量賦值,直接將地址賦值,賦完后,兩個(gè)變量指向一個(gè)內(nèi)存區(qū)域,并且相互影響.
拷貝原理:將被拷貝的對(duì)象復(fù)制一份,產(chǎn)生一個(gè)新的數(shù)據(jù),再將新數(shù)據(jù)的地址返回
2.1 淺拷貝
a.列表或字典的copy方法時(shí)淺拷貝、切片也是淺拷貝
b.copy.copy(對(duì)象) -- 復(fù)制指定的對(duì)象,產(chǎn)生一個(gè)新的對(duì)象
2.2 深拷貝
copy.deepcopy(對(duì)象) -- 復(fù)制指定的對(duì)象,產(chǎn)生一個(gè)新的對(duì)象。如果這個(gè)對(duì)象中有其他的對(duì)象,子對(duì)象也會(huì)被復(fù)制。
import copy # 拷貝前需導(dǎo)入copy模塊
stu2 = Student('Lisa', 18, 60)
stu4 = copy.copy(stu2)
stu2.name = 'Sara'
print(stu2, stu4)
3 內(nèi)存管理機(jī)制
3.1 數(shù)據(jù)的儲(chǔ)存
python的內(nèi)存空間也可以分為棧區(qū)間和堆區(qū)間。
變量(包括函數(shù)調(diào)用過(guò)程中的變量)都儲(chǔ)存在棧區(qū)間,對(duì)象都儲(chǔ)存在堆區(qū)間。
聲明變量或給變量賦值,是先在內(nèi)存(堆)中開(kāi)辟存儲(chǔ)數(shù)據(jù),然后將數(shù)據(jù)地址保存在變量中。
但是數(shù)字和字符串特殊,如果是用數(shù)字或者字符串給變量賦值,不會(huì)直接開(kāi)辟空間保存數(shù)據(jù),而是現(xiàn)在內(nèi)存檢測(cè)這個(gè)數(shù)據(jù)之前是否已經(jīng)儲(chǔ)存過(guò),如果已經(jīng)存儲(chǔ)直接用上次保存的數(shù)據(jù),沒(méi)有存儲(chǔ)才會(huì)開(kāi)辟新的空間保存數(shù)據(jù)。
list1 = [1,2]
list2 = [1,2]
print(id(list1), id(list2))
a = 10
b = copy.deepcopy(a) # 即使使用copy方法,地址還是一樣
print(id(a), id(b))
c = 'abc'
d = 'abc'
print(id(c), id(d))
3.2 內(nèi)存的釋放
python中每個(gè)對(duì)象都有一個(gè)熟悉叫引用計(jì)數(shù),用來(lái)保存當(dāng)前對(duì)象的引用個(gè)數(shù)。
python中的垃圾回收機(jī)制來(lái)判斷一個(gè)對(duì)象是否銷(xiāo)毀,就看這個(gè)對(duì)象的引用計(jì)數(shù)是否為零,如果為零就會(huì)被銷(xiāo)毀