Python说文解字_杂谈09

 1. 元类编程代码分析:

import numbers

class Field:
    pass

class IntField(Field):
    # 数据描述符:
    # 初始化
    def __init__(self,db_column=None,min_value=None,max_value=None):
        self._value = None
        self.min_value = min_value
        self.max_value = max_value
        self.db_column = db_column
        if min_value is not None:
            if not isinstance(min_value,numbers.Integral):
                raise ValueError("min_value must be int")
            elif min_value < 0:
                raise ValueError("min_value must be positive int")
        if max_value is not None:
            if not isinstance(max_value, numbers.Integral):
                raise ValueError("max_value must be int")
            elif max_value < 0:
                raise ValueError("max_value must be positive int")
        if min_value is not None and max_value is not None:
            if min_value > max_value:
                raise ValueError("min_value must be smaller than max_value")

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

    def __set__(self, instance, value):
        if not isinstance(value,numbers.Integral):
            raise ValueError("int value need")
        if value < self.min_value or value > self.max_value:
            raise ValueError("value must between min_value and max_value")
        self._value = value

class CharField(Field):

    def __init__(self,db_column,max_length=None):
        self._value = None
        self.db_column = db_column
        if max_length is None:
            raise ValueError("you must specify max_length for charfield")
        self.max_length = max_length

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

    def __set__(self, instance, value):
        if not isinstance(value,str):
            raise ValueError("string value need")
        if len(value) > self.max_length:
            raise ValueError("value len excess len of max_length")
        self._value = value

class ModelMetaClass(type):
    def __new__(cls, name,bases,attrs, **kwargs):
        if name == "BaseModel":
            return super().__new__(cls, name,bases,attrs, **kwargs)
        fields = {}
        for key,value in attrs.items():
            if isinstance(value,Field):
                fields[key] = value
        attrs_meta = attrs.get("Meta",None)
        _meta = {}
        db_table = name.lower()
        if attrs_meta is not  None:
            table = getattr(attrs_meta,"db_table",None)
            if table is not None:
                db_table = table
        _meta["db_table"] = db_table
        attrs["_meta"] = _meta
        attrs["fields"] = fields
        del attrs["Meta"]
        return super().__new__(cls, name,bases,attrs, **kwargs)

class BaseModel(metaclass=ModelMetaClass):
    def __init__(self, *args,**kwargs):
        for key,value in kwargs.items():
            setattr(self,key,value)
        return super().__init__()

    def save(self):
        fields = []
        values = []
        for key,value in self.fields.items():
            db_column = value.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 {db_table}({fields}) value({values})".format(db_table = self._meta["db_table"],fields=",".join(fields),values=",".join(values))

class User(BaseModel):
    name = CharField(db_column="name",max_length=10)
    age = IntField(db_column="age",min_value=1,max_value=100)

    class Meta:
        db_table = ""

if __name__ == '__main__':
    user = User(name = "bobby",age =28)
    # user.name = "bobby"
    # user.age = 28
    user.save()

  解析1:数据描述符部分:

    数据描述部分分为:数据描述和非数据描述:为了方便使用,我们通过共同继承一个Field类的方式直接用这个来,来进行数据描述和飞数据描述。

  解析2:我们知道type来生成动态类后面跟随(name,bases,attrs),类名,基类,属性,三个部分。我们在new一个元类的时候对他进行拆包处理。

  解析3:拆包过程我们对attrs属性分别重新定义属性当中的_meta和fields部分。

  解析4:判断过程:

  1.判断是否属于BaseModel这个子类,是的话返回元类

  2.生成一个fields = { } 的空字典永安里记录。

  3.循环遍历属性当中的项目得到key值和value值:这里得到

    * key = __model__ , value =__main__。

    * key = __qualname__  value = 'user'

    *  key = name  value= <_main__.charfField>

    * 记录一次:{'name': <__main__.CharField object at 0x0000028555A3CFD0>} (fields字典中)

    * 再记录一次:<__main__.IntField object at 0x0000028555AD7198> (到字典中)

    另外:bases = tuple  fileds = { }   name = str‘User’

   4. db_table 把table的名字记录到里面:db_table:'user"取小写

  5.最终把attrs的属性值中的User改为user,age,name,_meta:{db_table},fields都该改了

  {'__module__': '__main__', '__qualname__': 'User', 'name': <__main__.CharField object at 0x0000028555A3CFD0>, 'age': <__main__.IntField object at 0x0000028555AD7198>, '_meta': {'db_table': ''}, 'fields': {'name': <__main__.CharField object at 0x0000028555A3CFD0>, 'age': <__main__.IntField object at 0x0000028555AD7198>}}

_meta = {'db_table': ''}

fields = {'name': <__main__.CharField object at 0x0000028555A3CFD0>, 'age': <__main__.IntField object at 0x0000028555AD7198>}

   总结:这么做的目的就是在类形成之前,给类增加一些判断的功能,再使用这些属性的时候无需再添加了。让这些类具有一些天然的属性。

 2. Python的迭代协议:

  什么是迭代器?

  迭代器是什么?迭代器是访问集合内元素的一种方式,一般是用来遍历数据

  迭代器以下标的访问方式不一样,迭代器是不能反悔的,迭代器提供了一种惰性访问的方式(惰性访问,是在访问数据的时候才会生成或迭代)

  #[] list, __iter__

  # Iterable = __iter__  iterator = __next__ 

from collections.abc import Iterable,Iterator

a = {1,2}
b = iter(a)
print(isinstance(a,Iterator))
print(isinstance(a,Iterable))
print(isinstance(b,Iterator))
# False
# True
# True

猜你喜欢

转载自www.cnblogs.com/noah0532/p/10994052.html
今日推荐