python 经典类和新式类
DAY 12. python新式類和舊式類
繼承自object基類的類叫做新式類,否則叫做舊式類,python3中的類默認(rèn)是新式類,之前版本默認(rèn)是舊式類
root@kail:~# python python 2.7.15 (default,Jul 28 2018,11:29:29) [GCC 8.1.0] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> class A(): ... pass ... >>> a=A() >>> dir(a) ['__doc__','__module__']如上,在python2中定義一個類,不繼承任何基類,內(nèi)建屬性只有兩個,這就是舊式類,如果想要創(chuàng)建一個新式類,需要顯式的繼承object基類,如:
root@kail:~# python python 2.7.15 (default,Jul 28 2018,11:29:29) [GCC 8.1.0] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> class A(object): ... pass ... >>> dir(A) ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__']新式類默認(rèn)有很多屬性,都是從object基類中繼承過來的,而在python3中所有類默認(rèn)繼承object基類
Python 3.7.0 (v3.7.0:1bf9cc5093, Jun 27 2018, 04:59:51) [MSC v.1914 64 bit (AMD64)] on win32 Type "copyright", "credits" or "license()" for more information. >>> class A:pass >>> dir(A) ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__'] >>>每個屬性的具體用法參見Python——特殊屬性與方法
12.1 新式類和舊式類的區(qū)別
python 2.7
class A():name = 'A'age = 12class B():name = 'B'class C():name = 'C'class D(A,B):name = 'D'class E(A,C):name = 'E'age = 13class F(D,E):passprint F.name # D print F.age # 12上面的繼承關(guān)系是:
A,age=12DBAE,age=13CF顯然在age的繼承上,2.7使用了DFS,我們再看3.7
python 3.7
class A():name = 'A'age = 12class B():name = 'B'class C():name = 'C'class D(A,B):name = 'D'class E(A,C):name = 'E'age = 13class F(D,E):passprint(F.name) # D print(F.age) # 13顯然3.7沒有使用DFS,而是在每一次尋找入度為零的節(jié)點(diǎn),加入mro列表后刪除這條邊,再次尋找,以上面的代碼為例,第一個入讀為0的節(jié)點(diǎn)就是F,所以mro表的第一項(xiàng)就是F,刪除F及相連的邊,入度為0的就是DE,按照書寫代碼的順序第二項(xiàng)為D,第三項(xiàng)為E,依次,最終所有新式類繼承自object,所以最后一項(xiàng)就是object,繼承順序就是按mro列表的順序來的,可以使用mro()查看mro列表
print(F.mro()) # [<class '__main__.F'>, <class '__main__.D'>, <class '__main__.E'>, <class '__main__.A'>, <class '__main__.B'>, <class '__main__.C'>, <class 'object'>]也就是說,C3是先在水平方向上查找,再往上查找
12.2 總結(jié)
| 經(jīng)典類 | None | DFS | python2默認(rèn)經(jīng)典類 |
| 新式類 | object | C3 | python3默認(rèn)新式類 |
我嘗試在python3中通過重寫type元類寫出經(jīng)典類,但發(fā)現(xiàn)這樣寫出的類似乎不是真的經(jīng)典類,只是默認(rèn)屬性和經(jīng)典類差不多,MRO行為依舊和新式類一樣,可能是我代碼有問題,請各位大佬賜教
class Type(type):__bases__ = ()__base__ = None__mro__ = (None,)Foo1 = Type('Foo1',() ,{}) Foo2 = Type('Foo2', (), {}) Foo3 = Type('Foo3', (), {}) Foo4 = Type('Foo4', (Foo1, Foo2), {}) Foo5 = Type('Foo5', (Foo1, Foo3), {}) Foo6 = Type('Foo6', (Foo4, Foo5), {})if __name__ == '__main__':# base 為空時會多出兩個屬性,第一個與類描述有關(guān),第二個與弱拷貝有關(guān)print(dir(Foo1)) # ['__dict__', '__doc__', '__module__', '__weakref__']print(dir(Foo2)) # ['__dict__', '__doc__', '__module__', '__weakref__']print(dir(Foo3)) # ['__dict__', '__doc__', '__module__', '__weakref__']# base 不為空時,默認(rèn)屬性表現(xiàn)的和經(jīng)典類一樣print(dir(Foo4)) # ['__doc__', '__module__']print(dir(Foo5)) # ['__doc__', '__module__']print(dir(Foo6)) # ['__doc__', '__module__']# 假如定義的是經(jīng)典類,這里應(yīng)該不能調(diào)用mro方法,但這里調(diào)用了,說明本身就不對,并且mro列表最后是object,進(jìn)一步說明這還是一個新式類print(Foo1.mro()) # [<class '__main__.Foo1'>, <class 'object'>]print(Foo2.mro()) # [<class '__main__.Foo1'>, <class 'object'>]print(Foo3.mro()) # [<class '__main__.Foo1'>, <class 'object'>]print(Foo4.mro()) # [<class '__main__.Foo4'>, <class '__main__.Foo1'>, <class '__main__.Foo2'>, <class 'object'>]print(Foo5.mro()) # [<class '__main__.Foo5'>, <class '__main__.Foo1'>, <class '__main__.Foo3'>, <class 'object'>]# 清楚的看到MRO使用的是C3算法print(Foo6.mro()) # [<class '__main__.Foo6'>, <class '__main__.Foo4'>, <class '__main__.Foo5'>, <class '__main__.Foo1'>, <class '__main__.Foo2'>, <class '__main__.Foo3'>, <class 'object'>]# TODO: 如何在python3中定義經(jīng)典類,還是根本不能定義,拋磚引玉,請賜教總結(jié)
以上是生活随笔為你收集整理的python 经典类和新式类的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python微信语音转发方法_语音转发方
- 下一篇: Windows下Tomcat8的安装和闪