python元類

type() 內(nèi)置元類


# print(type('Hello'))

class Add():
    pass

# print(type(Add))  # Add 類
# print(type(Add()))  # Add()類的實(shí)例
# add = Add()
# print(type(add))    # add 實(shí)例化對象

# 利用 type() 函數(shù)動態(tài)創(chuàng)建一個類 ('func_name', (要繼承的父類), {類的屬性、類的實(shí)例屬性、類的方法})
# 注意!!! (要繼承的父類) 是一個元組[ 例子:(Add,) ]
print(type('Func', (), {})) 

Func1 = type('Func1', (), {'className': 'Func'})    #使用元類 type() 創(chuàng)建出一個對象,這個對象稱為“類”
func1 = Func1() #使用“類”來創(chuàng)建出實(shí)例對象
print(func1.className)

自定義元類

實(shí)現(xiàn) ORM(對象關(guān)系映射) 對數(shù)據(jù)庫的 '增、刪、改、查'

1. 使用描述器定義字段屬性

# 定義字段屬性的基類Field,它的用處主要用于識別類屬性中屬于字段的那些屬性
class Field(object):
    pass

# 整型字段屬性
class IntField(Field):
    def __init__(self, db_column=""):
        self._value = None # 表的數(shù)據(jù)
        self.db_column = db_column

    def __set__(self, instance, value):
        if not isinstance(value, int):
            raise ValueError("input should be a Integer")
        self._value = value

    def __get__(self, instance, owner):
        return self._value

# 字符型字段屬性
class  CharField(Field):
    def __init__(self, db_column=""):
        self._value  = None 
        self.db_column = db_column

    def __get__(self, instance, owner):
        return self._value

    def __set__(self, instance, value):
        if not isinstance(value, str):
            raise ValueError("input should be a String")
        self._value = value

2. 定義元類

class MetaModel(type):
    def __new__(cls, name, bases, attrs, **kwargs):
        fields = {}
        for key, val in attrs.items():
            # 把a(bǔ)ttrs中與數(shù)據(jù)庫表字段有關(guān)的列提取出來
            if isinstance(val, Field):
                fields[key] = val   # value 直接走描述器__get__()

        _meta = {}
        db_table = name.lower()  # 數(shù)據(jù)表名稱默認(rèn)取小寫類名稱
        _meta['db_table'] = db_table
        attrs['_meta'] = _meta
        attrs['_fields'] = fields

        # 以上過程相當(dāng)于對類進(jìn)行了修改
        return super(MetaModel, cls).__new__(cls, name, bases, attrs, **kwargs)

3. 定義模型基類

class Model(metaclass=MetaModel):
    def __init__(self, *args, **kwargs):
        for key, val in kwargs.items():
            setattr(self, key, val)
        return super(Model, self).__init__()

    def save(self):
        fields = []
        values = []
        for key, val in self._fields.items():
            db_column = val.db_column
            if db_column is None:
                db_column = key.lower()
            fields.append(db_column)
            value = getattr(self, key) # 字段的值
            values.append(str(value))
        sql = "insert {name} ({field}) values ({value})".format(name=self._meta['db_table'],field=','.join(fields),value=','.join(values))
        return sql

    def select(self):
        fields = []
        where = []
        for key, val in self._fields.items():
            db_column = val.db_column
            if db_column is None:
                db_column = key.lower()
            fields.append(db_column)
            v = getattr(self, key, None)
            if v is not None:
                where.append([key, str(v)])     # [key, str(v)] 等價(jià)于 字典的鍵值對
                
        # ['='.join(x) for x in where] => name=sean

        sql = 'select {fields} from {name} where {where}'.format(name=self._meta['db_table'], fields=','.join(fields),where=' and '.join(['='.join(x) for x in where]),)
        return sql
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 了解元類之前,先了解幾個魔術(shù)方法: __new__、__init__、__call__ __new__: 對象的創(chuàng)...
    大富帥閱讀 9,339評論 2 16
  • 最近接觸到一個對xml進(jìn)行序列化的python庫,實(shí)際上可以理解為一個小的ORM,只不過數(shù)據(jù)的來源是xml而不是數(shù)...
    TypingQuietly閱讀 3,080評論 0 5
  • 類也是對象,在理解元類之前,你需要先掌握Python中的類。Python中類的概念借鑒于Smalltalk,這顯得...
    雲(yún)凌禹閱讀 520評論 0 3
  • 僅供學(xué)習(xí),轉(zhuǎn)載請注明出處 元類實(shí)現(xiàn)ORM 上一篇章大概講述了元類的概念,實(shí)現(xiàn)使用元類的方式修改一個類的屬性大小寫修...
    Devops海洋的漁夫閱讀 823評論 0 16
  • 轉(zhuǎn)載 劉仲雨 兩句話掌握python最難知識點(diǎn)——元類 千萬不要被所謂“元類是99%的python程序員不會用到的...
    seven1010閱讀 703評論 0 0

友情鏈接更多精彩內(nèi)容