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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

python元类深入理解

發布時間:2023/11/27 生活经验 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python元类深入理解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1.python 中的類

在python中,類也是一個對象,只不過這個對象擁有生成實例的能力,我們一般使用class XXX來定義一個類,在python解釋器執行到這個地方的時候會自動創建出這個對象,python也為我們提供了手動創建類的方法,type()。type()這個方法對我們來說并不陌生,我們所熟知的用法是:class = type(instance),當傳入一個參數時,type()返回這個參數的類。而今天我們要用到的是type的另一個功能。type("classname",(object,),{"name":"jiao"})。當給type傳入三個參數時,就是一個手動創建類的方式。

class A():def __init__(self,name):self.name = nameprint("創建了一個實例")a = type("a",(A,),{"name":"jiao"}) 
print(a)              #<class '__main__.a'>
print(a.name)          #jiao
print(a("jiang"))      #創建了一個實例  #<__main__.a object at 0x00000280A973AA58>

?

type接收三個參數分別是:

classname: 要創建的class 的名稱

object:要創建類的父類所組成的元組

sttr_dict: 要創建類的屬性

type返回一個class,我們接收并賦值到一個變量上,現在這個變量就指向我們所創建的類,我們可以通過這個變量來使用類。

?

2.python 中的type

在python 中,幾乎所有的東西都是對象,這包括整數、字符串、函數以及類。它們全部都是對象,而且它們都是從一個類創建而來——type

3.__metaclass__屬性

python在創建類時,會按照如下的流程進行:

?

Foo中有__metaclass__這個屬性嗎?如果是,Python會在內存中通過__metaclass__創建一個名字為Foo的類對象(我說的是類對象,請緊跟我的思路)。如果Python沒有找到__metaclass__,它會繼續在Bar(父類)中尋找__metaclass__屬性,并嘗試做和前面同樣的操作。如果Python在任何父類中都找不到__metaclass__,它就會在模塊層次中去尋找__metaclass__,并嘗試做同樣的操作。如果還是找不到__metaclass__,Python就會用內置的type來創建這個類對象。

那么在__metaclass__中放置什么樣的代碼可以創建類呢?type,或者任何使用到type或者子類化type的東東都可以。

?

4.自定義元類

class UpperAttrMetaClass(type):def __new__(cls,class_name,class_parents,class_attr, *args, **kwargs):print("__new__")class_attr['name'] = "jiao"return type.__new__(cls,class_name,class_parents,class_attr)def __init__(self,*args,**kwargs):print("__init__")super().__init__(*args, **kwargs)self.__cache = {}def __call__(self, *args, **kwargs):print("__call__")if args in self.__cache:return self.__cache[args]else:obj = super().__call__(*args)self.__cache[args] = objreturn objclass A(metaclass=UpperAttrMetaClass):def __init__(self,name):self.name = nameprint("a.__init__")

?

?

5.類的創建流程

1.元類的__new__(),返回創建好的類。當我們想要改變創建方式的時候就要重寫這個方法。

2.元類的__init__(),初始化一些類的屬性

?

6.實例創建流程

1.元類的__call__(),創建一個實例時,首先調用這個方法,返回創建好的實例,所以我們可以通過改寫這個方法來改變實例創建過程,比如實現單例模式

2.類的__init__(),初始化實例屬性

?

7.元類的應用

1.單例模式

class Singleton(type):def __init__(cls,*args,**kwargs):cls.__instance = Nonesuper().__init__(*args,**kwargs)def __call__(cls, *args, **kwargs):if cls.__instance is None:cls.__instance = super().__call__(*args,**kwargs)return cls.__instanceelse:return cls.__instanceclass Spam(metaclass=Singleton):def __init__(self):print("Creating Spam")

?

2.緩存模式
import weakrefclass Cached(type):def __init__(cls,*args,**kwargs):super().__init__(*args,**kwargs)cls.__cache = weakref.WeakValueDictionary()def __call__(cls, *args, **kwargs):if args in cls.__cache:return cls.__cache[args]else:obj = super().__call__(*args)cls.__cache[args] = objreturn objclass Spams(metaclass=Cached):def __init__(self,name):print("Creating Spam({!r})".format(name))self.name = name

?

3.獲取屬性的定義順序

?

能過獲取到屬性的定義順序,我們就可以通過簡單的方法實現屬性到數據的映射,可以更加簡單的將類中的屬性數據化。

from collections import OrderedDictclass Typed:_excepted_type = type(None)def __init__(self,name=None):self._name = namedef __set__(self, instance, value):if not isinstance(value,self._excepted_type):raise TypeError("Excepted"+str(self._excepted_type))instance.__dict__[self._name] = valueclass Integer(Typed):_excepted_type = intclass Float(Typed):_excepted_type = floatclass String(Typed):_excepted_type = strclass OrderedMeta(type):def __new__(cls, clsname,bases,clsdict):d = dict(clsdict)order = []for name,value in clsdict.items():if isinstance(value,Typed):value._name = nameorder.append(name)d['_order'] = orderreturn type.__new__(cls,clsname,bases,d)@classmethoddef __prepare__(metacls, name, bases):return OrderedDict()#注:__prepare__該方法會在類定義一開始的時候調用,調用時以類名和基類名稱作為參數,它必須返回一個映射對象,供處理類定義體時調用#eg.
class Structure(metaclass=OrderedMeta):def as_csv(self):return ','.join(str(getattr(self,name)) for name in self._order)class Stock(metaclass=OrderedMeta):name = String()shares = Integer()price = Float()def __init__(self,name,shares,price):self.name = nameself.shares = sharesself.price = prices = Stock("haha",23,23.3)
print(s.name)
s = Stock(34,23,34)
# print(s.as_csv())

?

?

8.小結

元類主要就是在類和實例創建的時候發揮作用,來實現一些功能。

轉載于:https://www.cnblogs.com/jiaojianglong/p/11260944.html

總結

以上是生活随笔為你收集整理的python元类深入理解的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。