2019-08-12_Note_Day16

一、運算符重載

1. 運算符

python中所有的類型都是類,所以所有的數(shù)據(jù)都是對象
python中使用任意的運算符都是在調(diào)用對應類中的對應方法
每一個運算符對應的方法是固定的
某種數(shù)據(jù)是否支持某個運算符操作,由這個數(shù)據(jù)類型中是否實現(xiàn)了對應的方法決定

2. 運算符重載

在不同的類中實現(xiàn)同樣的運算符對應的函數(shù)
注意:類的對象默認情況下只支持:==, !=
class Student:
    def __init__(self, name, age, score=0):
        self.name = name
        self.age = age
        self.score = score

    # self -> 當前類的對象,也是運算符前的數(shù)據(jù)
    # other -> 運算符后面的數(shù)據(jù),類型根據(jù)運算規(guī)則的設計可以是任何類型的數(shù)據(jù)
    # a + b -> a.__add__(b)
    def __add__(self, other):
        # return self.age + other.age
        # return self.score + other.score
        # return self.score + other
        return Student(self.name + other.name, self.age + other.age, self.score + other.score)

    # a * b -> a.__mul__(b)
    def __mul__(self, other: int):
        list1 = []
        for _ in range(other):
            list1.append(copy.copy(self))
        return list1

    # a < b -> a.__lt__(b)
    # 小于和大于符號只需要重載一個,另一個自動支持
    def __lt__(self, other):
        return self.score < other.score

    # return [self for _ in range(other)]
    # return Student(self.name * other, self.age * other, self.score * other)

    def __repr__(self):
        return ''.join(['<', str(self.__dict__)[1:-1], '>'])


stu1 = Student('小明', 19, 90)
stu2 = Student('小花', 20, 78)

print(stu1 + stu2)
print(stu1 * 3)

students = [stu1, stu2, Student('小紅', 12, 100)]
students.sort()
# students.sort(key=lambda x: x.score)
print(students)

print(stu1 < stu2, stu1 > stu2)

二、淺拷貝和深拷貝

class Dog:
    def __init__(self, name, color):
        self.name = name
        self.color = color

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


class Person:
    def __init__(self, name, age, dog=None):
        self.name = name
        self.age = age
        self.dog = dog

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

1. 直接賦值

將變量中的地址直接賦值給新的變量,賦值后兩個變量的地址相同
p1 = Person('小明', 18, Dog('大黃', '黃色'))
p2 = p1
print(p1)
print(p2)
# <'name': '小明', 'age': 18, 'dog': <'name': '大黃', 'color': '黃色'>, id = 0x101d9f8d0>, id = 0x101d9f908
# <'name': '小明', 'age': 18, 'dog': <'name': '大黃', 'color': '黃色'>, id = 0x101d9f8d0>, id = 0x101d9f908
p1.name = '小花'
print(p1.name, p2.name)  # 小花 小花
p2.dog.color = '綠色'
print(p1.dog.color)  # 綠色

2. 拷貝

無論是淺拷貝還是深拷貝都會對原數(shù)據(jù)進行復制,產(chǎn)生新的地址
list1 = [1, 2, 3]
list2 = copy(list1)
list3 = deepcopy(list1)
print(id(list1), id(list2), id(list3))  # 4533504520 4533323464 4533504456

list1.append(100)
print(list2, list3)  # [1, 2, 3] [1, 2, 3]

3. 淺拷貝

字符串、列表和元組的切片,對象.copy(),以及copy模塊中的copy()都是淺拷貝
淺拷貝只拷貝當前對象,不會對子對象進行拷貝
p3 = copy(p1)

print(id(p1), id(p3))  # 4564163104 4564163384
print(id(p1.dog), id(p3.dog))  # 4564163048 4564163048

p1.name = 'Tom'
print(p1.name, p3.name)  # Tom 小花

p1.dog.color = '紅色'
print(p1.dog.color, p3.dog.color)  # 紅色 紅色

4. 深拷貝

copy模塊中的deepcopy方法是深拷貝
p4 = deepcopy(p1)
print(id(p1), id(p4))  # 4364675728 4364730776
print(id(p1.dog), id(p4.dog))  # 4364675672 4364730496

p1.name = 'Jack'
print(p1.name, p4.name)  # Jack Tom

p1.dog.color = '黑色'
print(p1.dog.color, p4.dog.color)  # 黑色 紅色

三、枚舉

枚舉值的特點

1. 可以通過有意義的屬性名直接顯示數(shù)據(jù)

2. 每個數(shù)據(jù)的值不能修改

3. 可以做到不同數(shù)據(jù)的值唯一

from enum import Enum
from enum import unique

@unique
class PokerNum(Enum):
    J = 11
    Q = 12
    K = 13
    A = 1


print(PokerNum.J.name)  # J
print(PokerNum.K.value, PokerNum.J.value > PokerNum.Q.value)  # 13 False

四、內(nèi)存管理

1. 內(nèi)存的開辟

內(nèi)存區(qū)間分為棧區(qū)間和堆區(qū)間
棧區(qū)間的內(nèi)存自動開辟和釋放,堆區(qū)間的內(nèi)存需要程序員手動開辟和釋放,但在python中已經(jīng)將堆區(qū)間內(nèi)存的開辟和釋放過程自動化
當給變量賦值時,系統(tǒng)會先在堆區(qū)間中開辟空間將數(shù)據(jù)保存,然后再將數(shù)據(jù)在堆區(qū)的地址存到棧區(qū)間的變量中
數(shù)字和字符串數(shù)據(jù)在開辟空間時,會先檢查內(nèi)存中之前是否已經(jīng)有當前數(shù)據(jù),如果有則直接使用之前的數(shù)據(jù),沒有會開辟新的空間保存當前數(shù)據(jù)

2. 內(nèi)存的釋放

棧區(qū)間:全局棧區(qū)間在程序結(jié)束后銷毀,函數(shù)棧區(qū)間在函數(shù)調(diào)用結(jié)束后銷毀
堆區(qū)間:對象是否銷毀是由這個對象的引用計數(shù)決定的,如果一個對象的引用計數(shù)為零,這個對象就會銷毀(垃圾回收機制)
注意:python中針對對象的循環(huán)引用已經(jīng)做了處理,程序員不需要針對循環(huán)引用問題寫額外的代碼
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內(nèi)容