abstrak:type 其實就是元類,type 是python 背后創(chuàng)建所有對象的元類 python 中的類的創(chuàng)建規(guī)則:假設(shè)創(chuàng)建Foo 這個類class Foo(Bar): def __init__(): pass Foo中有__metaclass__這個屬性嗎?如果有,Python會在內(nèi)存中通過__metaclass__創(chuàng)建一個名字為Foo的類對象,他是一個
type 其實就是元類,type 是python 背后創(chuàng)建所有對象的元類
python 中的類的創(chuàng)建規(guī)則:
假設(shè)創(chuàng)建Foo 這個類
class Foo(Bar): def __init__(): pass
Foo中有__metaclass__這個屬性嗎?如果有,Python會在內(nèi)存中通過__metaclass__創(chuàng)建一個名字為Foo的類對象,他是一個類,但是本身類就是對象,一個python文件模塊也屬于一個對象。
如果Python沒有找到__metaclass__,它會繼續(xù)在Bar(父類)中尋找__metaclass__屬性,并嘗試做和前面同樣的操作。
如果Python在任何父類中都找不到__metaclass__,它就會在模塊層次中去尋找__metaclass__,并嘗試做同樣的操作。
如果還是找不到__metaclass__,Python就會用內(nèi)置的type來創(chuàng)建這個類對象。
用途:元類的主要目的就是為了當(dāng)創(chuàng)建類時能夠自動地改變類,元類的主要用途是創(chuàng)建API。一個典型的例子是Django ORM。它允許你像這樣定義:
Flask sqlalchemy ORM 類的定義也是通過繼承一個被創(chuàng)建的類Base, 并且要注意sqlalchemy 中所有的表類必須繼承一個Base 對象,不然繼承后創(chuàng)建的Base的表將無法實現(xiàn)ORM映射;
sqlalchemy 實例:
from sqlalchemy.ext.declarative import declarative_base Base = declarative_base() class HotWordType(Base): # 表名稱 __tablename__ = 'hotWordType' # id typeName id = Column(Integer, primary_key=True) # 主鍵 typeName = Column(String(20), nullable=False) # 類型名 hotWord = relationship('HotWord', backref='hotWordType')
declarative_base 中的元類源碼:
The new base class will be given a metaclass that produces appropriate :class:`~sqlalchemy.schema.Table` objects and makes the appropriate :func:`~sqlalchemy.orm.mapper` calls based on the information provided declaratively in the class and any subclasses of the class. class DeclarativeMeta(type): def __init__(cls, classname, bases, dict_): if '_decl_class_registry' not in cls.__dict__: _as_declarative(cls, classname, cls.__dict__) type.__init__(cls, classname, bases, dict_) def __setattr__(cls, key, value): _add_attribute(cls, key, value)