python面向?qū)ο?凳枝、內(nèi)存管理和拷貝

1.多繼承

  • python中的類支持多繼承(讓一個類同時繼承多個類)
  • 多繼承的時候,子類只能繼承第一個父類中所有的屬性和方法省古,后面的父類中只有字段和方法可以被繼承
  • 實際上:子類能繼承第一個父類的所有屬性和方法粥庄,后面的父類,只能繼承前面沒有的字段和方法(不重名的)
class Animal(object):
    num = 100
    name = 'hh'

    def __init__(self):
        self.age = 0
        self.gender = 'male'

    @classmethod
    def func1(cls):
        print('動物類的類方法')


class Fly(object):
    name = '飛行器'

    def __init__(self):
        self.height = 100
        self.time = 20
        self.spend = 100

    def func1(self):
        print('紅紅火火')

    def func2(self):
        print('飛行的對象方法')


class Bird(Animal,Fly):
    pass


bird = Bird()
print(Bird.num,Bird.name)
bird.func1()
bird.func2()
print(bird.age)

運算符重載

import copy

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

    def __repr__(self):
        return str(self.__dict__)

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

    def __mul__(self, other):
        list1=[]
        for _ in range(other):
            list1.append(copy.copy(other))
        return list1

    # 大于和小于運算符只需要重載一個,另外一個自動實現(xiàn)
    def __lt__(self, other):
        return self.score < other.score


stu1 = Student('小明', 12, 34)
stu2 = Student('小胡', 15, 67)
stu3 = Student('小胡', 15, 47)

print(stu1 == stu2, stu1 != stu2)   # False True
print(stu1 + stu2)  # return self.age + other.age 27
print(stu1 + stu2)  # return self.score + other.score 101
print(stu1 + stu2)  # return self.name + other.name,self.age + other.age,self.score + other.score   ('小明小胡', 27, 101)
print(stu1 + stu2)  # return 'abc' abc
students = [stu1, stu2, stu3]
students.sort()
print(students)

""" = = = HJR = = = """

from copy import copy, deepcopy
# 支持所有類型的拷貝
class Dog:
    def __init__(self,name,color):
        self.name=name
        self.color=color

    def __repr__(self):
        return '<%s,id:%s>' % (str(self.__dict__)[1:-1],hex(id(self)))


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

    def __repr__(self):
        return '<%s,id:%s>' % (str(self.__dict__)[1:-1],hex(id(self)))


p1 = Person('小米',18,Dog('大黃','黃色'))

1.直接賦值

將變量中的地址直接賦給新的變量白嘁,賦值后兩個變量的地址相同

p2 = p1
print(id(p1),id(p2))   # 3032819635872 3032819635872
p1.name = '小花'
print(p1.name,p2.name)   # 小花 小花

2.拷貝

不管是淺拷貝還是深拷貝都會對原數(shù)據(jù)進行賦值產(chǎn)生新的地址
淺拷貝只拷貝當前對象坑鱼,不會拷貝子對象,還是與原來的子對象相關聯(lián)
深拷貝拷貝所有絮缅,完全與原對象分離

print(id(p1),id(copy(p1)),id(deepcopy(p1)))  # 2045139556000 2045139556168 2045139556728

3.淺拷貝

字符串鲁沥、列表和元祖的切片;對象.copy();copy模塊中的copy方法都是淺拷貝

p3 = copy(p1)
print(p1,p3)   # <'name': '小花', 'age': 18, 'dog': <'name': '大黃', 'color': '黃色',id:0x29a6c9213c8>,id:0x29a6c921668> <'name': '小花', 'age': 18, 'dog': <'name': '大黃', 'color': '黃色',id:0x29a6c9213c8>,id:0x29a6c921668>
p3.dog.name = '哈尼'
p3.name = '小童'
print(p1,p3)   # <'name': '小花', 'age': 18, 'dog': <'name': '哈尼', 'color': '黃色',id:0x285c82e13c8>,id:0x285c82e1668> <'name': '小童', 'age': 18, 'dog': <'name': '哈尼', 'color': '黃色',id:0x285c82e13c8>,id:0x285c82e1940>
# 發(fā)現(xiàn)dog中的改變會一同改變


# 4.深拷貝
"""
copy模塊中的deepcopy為深拷貝盟蚣,有且僅有這一個
"""
p4 = deepcopy(p1)
print(p1,p4)   # <'name': '小花', 'age': 18, 'dog': <'name': '哈尼', 'color': '黃色',id:0x15086f915f8>,id:0x15086f916a0> <'name': '小花', 'age': 18, 'dog': <'name': '哈尼', 'color': '黃色',id:0x15086f915f8>,id:0x15086faae10>
p4.dog.name = '大華'
p4.name = '小美'
print(p1,p4)  # <'name': '小花', 'age': 18, 'dog': <'name': '哈尼', 'color': '黃色',id:0x1d71fee15f8>,id:0x1d71fee16a0> <'name': '小美', 'age': 18, 'dog': <'name': '大華', 'color': '黃色',id:0x1d71fefaeb8>,id:0x1d71fefada0>

練習

a = ['color','height','background']
b = [a,'aaa','bbb']
c1 = b
c2 = copy(b)
c3 = deepcopy(b)
a[-1] = ['BG']
b.append('ccc')
# [['color','height',['BG']],'aaa','bbb','ccc']
# [['color','height',['BG']],'aaa','bbb']
# [['color', 'height', 'background'], 'aaa', 'bbb']
# 問題:print(c1),print(c2),print(c3)的打印結(jié)果

""" = = = HJR = = = """
from enum import Enum,unique

枚舉值的特點:

1.可以通過有意義的屬性名直接顯示數(shù)據(jù)
2.每個數(shù)據(jù)的值不能修改
3.可以做到不同的數(shù)據(jù)是唯一的

unique確保不同的數(shù)據(jù)是唯一的
在類中繼承Enum可以做到枚舉

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


print(PokerNum.J)    # PokerNum.J
print(PokerNum.J.value > PokerNum.Q.value)   # False

""" = = = HJR = = = """

獲取引用計數(shù)

from sys import getrefcount

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

內(nèi)存區(qū)間分為棧區(qū)間和堆區(qū)間黍析;棧區(qū)間的內(nèi)存自動開辟自動釋放,堆區(qū)間的內(nèi)存需要程序員手動開辟手動釋放屎开;
但是python已經(jīng)將堆區(qū)間內(nèi)存的開辟和釋放自動化

a. 當給變量賦值的時候阐枣,系統(tǒng)會先在堆區(qū)間中開辟空間將數(shù)據(jù)存起來,然后再將數(shù)據(jù)在隊中的地址存到變量中奄抽,變量存在棧區(qū)間蔼两;
b. 數(shù)字和字符串數(shù)據(jù)在開辟空間的時候,會先檢查內(nèi)存中之前是否已經(jīng)有這個數(shù)據(jù)逞度,
如果有额划,直接使用之前的數(shù)據(jù),不再開辟空間档泽,如果沒有俊戳,才重新開辟空間

a, b = [1, 2, 3], [1, 2, 3]
print(id(a), id(b), a is b)   # 1567575270024 1567575270088 False
print(id(a[0]),id(b[0]), a[0] is b[0])  # 140726342640464 140726342640464 True
a, b = 10, 10
print(id(a), id(b), a is b)   # 140726342640752 140726342640752 True
a, b = '10', '10'
print(id(a), id(b), a is b)   # 1567575737208 1567575737208 True

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

棧區(qū)間:全局棧區(qū)間在程序結(jié)束后銷毀揖赴,函數(shù)棧區(qū)間在函數(shù)調(diào)用結(jié)束后銷毀(自動)
堆區(qū)間:看一個對象是否銷毀,就看這個對象的引用計數(shù)是否為0抑胎;
如果一個對象的引用計數(shù)為0燥滑,這個對象就銷毀,反之不銷毀(垃圾回收機制)
注意:python中針對對象的循環(huán)引用阿逃,已經(jīng)做了處理铭拧,程序員不需要寫額外的代碼來解決循環(huán)引用的問題

a = [1, 2, 3]
print(getrefcount(a))  # 2 會打印比之前多一個引用,因為函數(shù)本身會有一個

def fun(a={}):
    a[1]=3
    return a


print(fun())
print(fun())

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末恃锉,一起剝皮案震驚了整個濱河市搀菩,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌破托,老刑警劉巖肪跋,帶你破解...
    沈念sama閱讀 221,331評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異炼团,居然都是意外死亡澎嚣,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,372評論 3 398
  • 文/潘曉璐 我一進店門瘟芝,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人褥琐,你說我怎么就攤上這事锌俱。” “怎么了敌呈?”我有些...
    開封第一講書人閱讀 167,755評論 0 360
  • 文/不壞的土叔 我叫張陵贸宏,是天一觀的道長。 經(jīng)常有香客問我磕洪,道長吭练,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,528評論 1 296
  • 正文 為了忘掉前任析显,我火速辦了婚禮鲫咽,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘谷异。我一直安慰自己分尸,他們只是感情好,可當我...
    茶點故事閱讀 68,526評論 6 397
  • 文/花漫 我一把揭開白布歹嘹。 她就那樣靜靜地躺著箩绍,像睡著了一般。 火紅的嫁衣襯著肌膚如雪尺上。 梳的紋絲不亂的頭發(fā)上材蛛,一...
    開封第一講書人閱讀 52,166評論 1 308
  • 那天圆到,我揣著相機與錄音,去河邊找鬼卑吭。 笑死构资,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的陨簇。 我是一名探鬼主播吐绵,決...
    沈念sama閱讀 40,768評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼河绽!你這毒婦竟也來了己单?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,664評論 0 276
  • 序言:老撾萬榮一對情侶失蹤耙饰,失蹤者是張志新(化名)和其女友劉穎纹笼,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體苟跪,經(jīng)...
    沈念sama閱讀 46,205評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡廷痘,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,290評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了件已。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片笋额。...
    茶點故事閱讀 40,435評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖篷扩,靈堂內(nèi)的尸體忽然破棺而出兄猩,到底是詐尸還是另有隱情,我是刑警寧澤鉴未,帶...
    沈念sama閱讀 36,126評論 5 349
  • 正文 年R本政府宣布枢冤,位于F島的核電站,受9級特大地震影響铜秆,放射性物質(zhì)發(fā)生泄漏淹真。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,804評論 3 333
  • 文/蒙蒙 一连茧、第九天 我趴在偏房一處隱蔽的房頂上張望核蘸。 院中可真熱鬧,春花似錦梅屉、人聲如沸值纱。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,276評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽虐唠。三九已至,卻和暖如春惰聂,著一層夾襖步出監(jiān)牢的瞬間疆偿,已是汗流浹背咱筛。 一陣腳步聲響...
    開封第一講書人閱讀 33,393評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留杆故,地道東北人迅箩。 一個月前我還...
    沈念sama閱讀 48,818評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像处铛,于是被迫代替她去往敵國和親饲趋。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,442評論 2 359

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