日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

新式类和经典类的区别类的特殊方法单例模式

發(fā)布時間:2025/3/21 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 新式类和经典类的区别类的特殊方法单例模式 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

目錄:

  • 新式類和經(jīng)典類的區(qū)別
  • 重寫特殊的構(gòu)造方法
  • 類的特殊方法
  • 單例模式原理及作用

新式類和經(jīng)典類的區(qū)別:

1)首先,寫法不一樣:

 class A: #經(jīng)典類寫法passclass B(object): #新式類寫法pass

2)多繼承中,新式類采用廣度優(yōu)先搜索,而舊式類是采用深度優(yōu)先搜索,python3中全是廣度優(yōu)先

3)在繼承中新式類和經(jīng)典類寫法區(qū)別

SchoolMember.__init__(self,name,age,sex) #經(jīng)典類寫法super(Teacher,self).__init__(name,age,sex) #新式類寫法


代碼展示

class D:def talk(self):print('D')class B(D):pass# def talk(self):# print('B')class C(D):passdef talk(self):print('C')class A(B,C):pass# def talk(self):# print('A')a = A() a.talk()

重寫特殊的構(gòu)造方法

  • 注:如果一個類的構(gòu)造方法被重寫,那么就需要調(diào)用超類的構(gòu)造方法,否則對象可能不能給被正確的初始化
  • 其實調(diào)用超類構(gòu)造方法很容易,SongBird類中只添加一行代碼
  • python 經(jīng)典類寫法: Bird.__init__(self)新式類寫法: super(SongBird,self).__init__()
  • 如果將下面代碼沒有2中的那句調(diào)用父類Bird中的self.hungry方法會報錯
  • if self.hungry == True: AttributeError: SongBird instance has no attribute 'hungry'

    新式類,經(jīng)典類,無超類構(gòu)造方法報錯

    class Bird:def __init__(self):self.hungry = Truedef eat(self):if self.hungry == True:print("Aaaah...")self.hungry = Falseelse:print("no, thanks") a = Bird() a.eat() a.eat()class SongBird(Bird):def __init__(self):# Bird.__init__(self) # 經(jīng)典類寫法# super(SongBird,self).__init__() # 新式類寫法self.sound = 'Squawk'def sing(self):print(self.sound) b = SongBird() b.sing() b.eat()

    類的特殊方法

    __doc__  表示類的描述信息 class Foo:""" 輸出類的描述類信息 """def func(self):pass print(Foo.__doc__) #運(yùn)行結(jié)果:描輸出類的描述類信息 __call__ 對象后面加括號,觸發(fā)執(zhí)行
    • 作用:構(gòu)造方法__init__的執(zhí)行是由創(chuàng)建對象觸發(fā)的,即:對象 = 類名()
    • 對于 call 方法的執(zhí)行是由對象后,括號觸發(fā)的,即:對象() 或者 類()()

    執(zhí)行__call__方法

    class Dog(object):def __init__(self,name):self.name = '實例變量'self.name = namedef __call__(self, *args, **kwargs):print("running call")print(args,kwargs) d = Dog("ChenRonghua") d(name='tom') # 如果只實例化,而不d()調(diào)用,__call__函數(shù)不會執(zhí)行# 運(yùn)行結(jié)果: # running call # () {'name': 'tom'} __str__ 如果一個類中定義了__str__方法,在打印對象時,默認(rèn)輸出該方法的返回值** class Foo:def __str__(self):return 'alex li' obj = Foo() print(obj) # 輸出:alex li __dict__ 查看類或?qū)ο笾械乃谐蓡T class Province:country = 'China'def __init__(self, name, count):self.name = nameself.count = countdef func(self, *args, **kwargs):print('func') # 獲取類的成員,即:靜態(tài)字段、方法、 print(Province.__dict__) # 輸出:{'country': 'China', '__module__': '__main__', 'func': <function func at 0x10be30f50>, '__init__': <function __init__ at 0x10be30ed8>, '__doc__': None}obj1 = Province('HeBei',10000) print(obj1.__dict__) # 獲取 對象obj1 的成員 # 輸出:{'count': 10000, 'name': 'HeBei'}obj2 = Province('HeNan', 3888) print(obj2.__dict__) # 獲取 對象obj1 的成員 # 輸出:{'count': 3888, 'name': 'HeNan'} _getitem__、__setitem__、__delitem__ 作用:用于索引操作,如字典。以上分別表示獲取、設(shè)置、刪除數(shù)據(jù) class Foo(object):def __getitem__(self, key):print('__getitem__', key)def __setitem__(self, key, value):print('__setitem__', key, value)def __delitem__(self, key):print('__delitem__', key)obj = Foo() result = obj['k1'] # __getitem__ k1 obj['k2'] = 'wupeiqi' # __setitem__ k2 wupeiqi del obj['k1'] # __delitem__ k1 __new__ \ __metaclass__ 作用: __metaclass__定義這個類以怎樣的形式被創(chuàng)建 class User(object):def __init__(self,name,age):print('__init__')def __new__(cls, *args, **kwargs):print("__new__",args,kwargs)return object.__new__(cls) # 調(diào)用一下object的__new__方法否則不往下走 d = User('tom',100)# 運(yùn)行結(jié)果: # __new__ ('tom', 100) {} # __init__

    __new__和__init__的區(qū)別

    • __new__是一個靜態(tài)方法,而__init__是一個實例方法.
    • __new__方法會返回一個創(chuàng)建的實例,而__init__什么都不返回.
    • 只有在__new__返回一個cls的實例時后面的__init__才能被調(diào)用.
    • 當(dāng)創(chuàng)建一個新實例時調(diào)用__new__,初始化一個實例時用__init__.

    type生成類調(diào)用順序

    • new : 先于__init__方法,每生成一個實例執(zhí)行一次
    • init : __init__方法每生成一個實例對象就會執(zhí)行一次
    • call : 后與__init__方法,C()() 使用類再加一個括號調(diào)用, C為類名稱
    • del : 析構(gòu)方法,刪除無用的內(nèi)存對象(當(dāng)程序結(jié)束會自動自行析構(gòu)方法)
    class Student(object):def __new__(cls, *args, **kwargs):print('__new__')return object.__new__(cls) # 必須返回父類的__new__方法,否則不不執(zhí)行__init__方法,無法創(chuàng)建實例def __init__(self,name):print('__init__')self.name = namedef __str__(self): # 作用:打印實例時顯示指定字符串,而不是內(nèi)存地址print('__str__')return self.namedef __call__(self, *args, **kwargs): # 當(dāng)執(zhí)行C()(*args) 或者 s1(*args) 就會執(zhí)行__call__print('__call__',*args)def __del__(self): # 作用:清除無用的實例對內(nèi)存的暫用print('__del__')#1、實例化時機(jī)會執(zhí)行__new__、__init__ s1 = Student('tom')#2、執(zhí)行 實例() 就會執(zhí)行__call__ 方法,并將參數(shù)傳遞給__call__函數(shù) s1('call01')#3、當(dāng)打印實例時就會執(zhí)行 __str__ 方法下返回的字符串(默認(rèn)返回的實例地址) print(s1)#4、析構(gòu)方法:當(dāng)刪除實例時就會調(diào)用 __del__ 方法 del s1 # 析構(gòu)方法作用:在程序結(jié)束后會自動執(zhí)行析構(gòu)方法刪除所有實例 # 但是在程序運(yùn)行時有很多實例是無用的,但是python內(nèi)存回收機(jī)制卻不會自動刪除他們,這樣就浪費內(nèi)存 # 我們可以執(zhí)行 del s1 ,那么在程序運(yùn)行時,python內(nèi)存回收機(jī)制會檢測到這些實例時無用的,才會刪除 # 其實我們執(zhí)行del s1,并沒有回收內(nèi)存,只不過是摘除門牌號,python內(nèi)存回收機(jī)制發(fā)現(xiàn)沒有門牌號后會自動回收內(nèi)存

    單例模式原理及作用

  • 單例模式:永遠(yuǎn)用一個對象得實例,避免新建太多實例浪費資源
  • 實質(zhì):使用__new__方法新建類對象時先判斷是否已經(jīng)建立過,如果建過就使用已有的對象
  • 使用場景:如果每個對象內(nèi)部封裝的值都相同就可以用單例模式
  • 創(chuàng)建單例模式舉例

    class Foo(object):instance = Nonedef __init__(self):self.name = 'alex'def __new__(cls, *args, **kwargs):if Foo.instance:return Foo.instanceelse:Foo.instance = object.__new__(cls,*args,**kwargs)return Foo.instanceobj1 = Foo() # obj1和obj2獲取的就是__new__方法返回的內(nèi)容 obj2 = Foo() print(obj1,obj2) # 運(yùn)行結(jié)果: <__main__.Foo object at 0x00D3B450> <__main__.Foo object at 0x00D3B450># 運(yùn)行結(jié)果說明: # 這可以看到我們新建的兩個Foo()對象內(nèi)存地址相同,說明使用的?同一個類,沒有重復(fù)建立類

    參考來自于此

    總結(jié)

    以上是生活随笔為你收集整理的新式类和经典类的区别类的特殊方法单例模式的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。