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

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 人文社科 > 生活经验 >内容正文

生活经验

python中的元类_python中的元类

發(fā)布時(shí)間:2023/11/27 生活经验 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python中的元类_python中的元类 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

類也是對(duì)象,但是類有創(chuàng)建對(duì)象的能力

動(dòng)態(tài)創(chuàng)建一個(gè)類:

classmonkey():defbanana(self):print 'banana!'

defapple(self):print 'i want apple!'monkey_child= type('monkey_child', (monkey,), {'apple': apple})

hasattr(monkey,'apple')

false

hasattr(monkey_child,'apple')

true

type的語(yǔ)法:type(類名,父類的元組(針對(duì)繼承的情況,可以為空),包含屬性的字典(名稱和值))

創(chuàng)建類的就是元類,type是所有類的元類,類屬性__class__可以看到元類是什么

>>> a=1

>>>type(a)

>>> type(a.__class__)

創(chuàng)建一個(gè)類的過(guò)程:搜索__metaclass__是否有指定,否則搜索父類中的__metaclass__,最終應(yīng)該找到type或是type的子類

由于python中鴨子類型的概念,__metaclass__實(shí)際上不一定是一個(gè)類,也可以是一個(gè)函數(shù)

defupper_attr(future_class_name, future_class_parents, future_class_attr):

attrs= ((name, value) for name, value in future_class_attr.items() if not name.startswith('__'))

uppercase_attr= dict((name.upper(), value) for name, value inattrs)returntype(future_class_name, future_class_parents, uppercase_attr)classFoo(object):__metaclass__ =upper_attr

bar= 'aip'

printFoo.BAR>>>'aip'

在Python3中我們?cè)诙x類時(shí)通過(guò)傳入metaclass的參數(shù)來(lái)設(shè)定,如上代碼就應(yīng)該寫成class Foo(metaclass=upper_attr)。

metaclass可以是一個(gè)類

classUpperAttrMetaclass(type):def __new__(cls, name, bases, dct):

attrs= ((name, value) for name, value in dct.items() if not name.startswith('__')

uppercase_attr= dict((name.upper(), value) for name, value inattrs)return type.__new__(cls, name, bases, uppercase_attr)

__new__在__init__之前被調(diào)用,用于創(chuàng)建和返回對(duì)象,由__new__是一個(gè)類方法,我們需要傳入實(shí)例對(duì)象cls。

為了表明繼承關(guān)系,以上代碼可以寫成

classUpperAttrMetaclass(type):def __new__(cls, name, bases, dct):

attrs= ((name, value) for name, value in dct.items() if not name.startswith('__'))

uppercase_attr= dict((name.upper(), value) for name, value inattrs)return super(UpperAttrMetaclass, cls).__new__(cls, name, bases, uppercase_attr)

為什么要用metaclass類而不是函數(shù)?

由于__metaclass__可以接受任何可調(diào)用的對(duì)象,那為何還要使用類呢,因?yàn)楹茱@然使用類會(huì)更加復(fù)雜啊?這里有好幾個(gè)原因:

1) 意圖會(huì)更加清晰。當(dāng)你讀到UpperAttrMetaclass(type)時(shí),你知道接下來(lái)要發(fā)生什么。

2) 你可以使用OOP編程。元類可以從元類中繼承而來(lái),改寫父類的方法。元類甚至還可以使用元類。

3) 你可以把代碼組織的更好。當(dāng)你使用元類的時(shí)候肯定不會(huì)是像我上面舉的這種簡(jiǎn)單場(chǎng)景,通常都是針對(duì)比較復(fù)雜的問(wèn)題。將多個(gè)方法歸總到一個(gè)類中會(huì)很有幫助,也會(huì)使得代碼更容易閱讀。

4) 你可以使用__new__, __init__以及__call__這樣的特殊方法。它們能幫你處理不同的任務(wù)。就算通常你可以把所有的東西都在__new__里處理掉,有些人還是覺得用__init__更舒服些。

根據(jù)http://python3-cookbook.readthedocs.io/zh_CN/latest/c08/p07_calling_method_on_parent_class.html 可以知道,我們應(yīng)該在繼承并改寫的代碼中盡量使用super訪問(wèn)父類,而不是直接訪問(wèn)父類。

classUpperAttrMetaclass(type):def __new__(cls, name, bases, dct):

attrs= ((name, value) for name, value in dct.items() if not name.startswith('__'))

uppercase_attr= dict((name.upper(), value) for name, value inattrs)return super(UpperAttrMetaclass, cls).__new__(cls, name, bases, uppercase_attr)

參考:http://blog.jobbole.com/21351/

其中有一個(gè)Django的ORM的例子,學(xué)習(xí)之

總結(jié)

以上是生活随笔為你收集整理的python中的元类_python中的元类的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

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