Explain Word _ Python-talk 09

 1. metaclass programming code Analysis:

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()

 

 

  Resolution 1: Data Descriptor portion:

    Data description section is divided into: data and non-data description Description: For ease of use, we have inherited a Field class way through the joint use this directly, for data description and fly data description.

  Resolution 2: We know the type generating a dynamic class followed later (name, bases, attrs), the name of the class, the base class attributes, three sections. We treated him unpacking in new metaclass time.

  Parsing 3: unpacking we are redefining _meta fields and among some of the properties of attrs attribute.

  Parsing 4: Analyzing Process:

  1. BaseModel determines whether this subclass, it is returned metaclass

  2. Generate a blank fields = {} Wing dictionary record.

  3. The loop through which the item attribute key value derived from the value obtained: Here give

    * key = __model__ , value =__main__。

    * key = __qualname__  value = 'user'

    *  key = name  value= <_main__.charfField>

    * Record time: { 'name': <__ main __ CharField object at 0x0000028555A3CFD0.>} (Fields dictionary)

    * Recorded once again: <__ main __ IntField object at 0x0000028555AD7198.> (The dictionary)

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

   4. db_table record to the table name which: db_table: 'user "to take lowercase

  The final value of the attribute of the User to attrs user, age, name, _meta: {db_table}, fields that have changed

  {'__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>}

   Summary: The goal is, before the formation of the class, to add some class to determine the function of time and then use these properties no longer added. Let these classes have some natural attributes.

 

 2. Python iteration protocol:

  What is an iterator?

  What iterators are? Iterator is a way to access the set of elements, the data is generally used to iterate

  Iterator visit the following subject in a different way, iterators can not go back, iterators provides a way to access the inert (inert access is only generated when accessing or iterative data)

  #[] 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

 

Guess you like

Origin www.cnblogs.com/noah0532/p/10994052.html