1.python 中的類
在python中,類也是乙個物件,只不過這個物件擁有生成例項的能力,我們一般使用class ***來定義乙個類,在python直譯器執行到這個地方的時候會自動建立出這個物件,python也為我們提供了手動建立類的方法,type()。type()這個方法對我們來說並不陌生,我們所熟知的用法是:class = type(instance),當傳入乙個引數時,type()返回這個引數的類。而今天我們要用到的是type的另乙個功能。type("classname",(object,),)。當給type傳入三個引數時,就是乙個手動建立類的方式。
classa():def __init__(self,name):
self.name=nameprint("建立了乙個例項")
a= type("a",(a,),)print(a) #
print(a.name) #jiao
print(a("jiang")) #建立了乙個例項
#<__main__.a object at>
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.自定義元類
classupperattrmetaclass(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] =objreturnobjclass a(metaclass=upperattrmetaclass):def __init__(self,name):
self.name=nameprint("a.__init__")
5.類的建立流程
1.元類的__new__(),返回建立好的類。當我們想要改變建立方式的時候就要重寫這個方法。
2.元類的__init__(),初始化一些類的屬性
6.例項建立流程
1.元類的__call__(),建立乙個例項時,首先呼叫這個方法,返回建立好的例項,所以我們可以通過改寫這個方法來改變例項建立過程,比如實現單例模式
2.類的__init__(),初始化例項屬性
7.元類的應用
1.單例模式
classsingleton(type):def __init__(cls,*args,**kwargs):
cls.__instance =none
super().__init__(*args,**kwargs)def __call__(cls, *args, **kwargs):if cls.__instance isnone:
cls.__instance = super().__call__(*args,**kwargs)return cls.__instance
else:return cls.__instance
class spam(metaclass=singleton):def __init__(self):print("creating spam")
2.快取模式
importweakrefclasscached(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] =objreturnobjclass spams(metaclass=cached):def __init__(self,name):print("creating spam()".format(name))
self.name= name
3.獲取屬性的定義順序
能過獲取到屬性的定義順序,我們就可以通過簡單的方法實現屬性到資料的對映,可以更加簡單的將類中的屬性資料化。
from collections importordereddictclasstyped:
_excepted_type=type(none)def __init__(self,name=none):
self._name=namedef __set__(self, instance, value):if notisinstance(value,self._excepted_type):raise typeerror("excepted"+str(self._excepted_type))
instance.__dict__[self._name] =valueclassinteger(typed):
_excepted_type=intclassfloat(typed):
_excepted_type=floatclassstring(typed):
_excepted_type=strclassorderedmeta(type):def __new__(cls, clsname,bases,clsdict):
d=dict(clsdict)
order=for name,value inclsdict.items():ifisinstance(value,typed):
value._name=name
d['_order'] =orderreturn type.__new__(cls,clsname,bases,d)
@classmethoddef __prepare__(metacls, name, bases):returnordereddict()#注:__prepare__該方法會在類定義一開始的時候呼叫,呼叫時以類名和基類名稱作為引數,它必須返回乙個對映物件,供處理類定義體時呼叫
#eg.
class structure(metaclass=orderedmeta):defas_csv(self):return ','.join(str(getattr(self,name)) for name inself._order)class stock(metaclass=orderedmeta):
name=string()
shares=integer()
price=float()def __init__(self,name,shares,price):
self.name=name
self.shares=shares
self.price=price
s= stock("haha",23,23.3)print(s.name)
s= stock(34,23,34)#print(s.as_csv())
8.小結
元類主要就是在類和例項建立的時候發揮作用,來實現一些功能。
python元類的使用 Python的元類如何使用
這次給大家帶來python的元類如何使用,使用python元類的注意事項有哪些,下面就是實戰案例,一起來看一下。今天我的任務就是徹底明白什麼是元類,一起看看。要搞懂元類,我們還是先從物件說起。python 一切皆物件,這句話你一定有聽說過 現在你就聽說了 乙個數字是物件,乙個字串是物件,乙個列表是物...
python 元類程式設計 python的元類程式設計
一 property動態屬性 給類中的乙個方法函式加上 property裝飾器,將這個方法變成屬性描述符,將獲取方法變為獲取屬性。class user def init self,name,birthday self.name name self.birthday birthday property...
python元類的使用 Python 元類使用講解
我要一大群的類都具有一種特點,我怎麼給他們加上呢?模板嘛,我從這個模板建立一群類不就ok了?那就需要元類了。定義乙個元類 就是乙個類的模板!莫多想,還要記住這是類級別的,不是物件級別的!如下 class mymeta type def init cls,name,bases,dic print cl...