type() 内置元类
# print(type('Hello'))
class Add():
pass
# print(type(Add)) # Add 类
# print(type(Add())) # Add()类的实例
# add = Add()
# print(type(add)) # add 实例化对象
# 利用 type() 函数动态创建一个类 ('func_name', (要继承的父类), {类的属性、类的实例属性、类的方法})
# 注意!!! (要继承的父类) 是一个元组[ 例子:(Add,) ]
print(type('Func', (), {}))
Func1 = type('Func1', (), {'className': 'Func'}) #使用元类 type() 创建出一个对象,这个对象称为“类”
func1 = Func1() #使用“类”来创建出实例对象
print(func1.className)
自定义元类
实现 ORM(对象关系映射) 对数据库的 '增、删、改、查'
1. 使用描述器定义字段属性
# 定义字段属性的基类Field,它的用处主要用于识别类属性中属于字段的那些属性
class Field(object):
pass
# 整型字段属性
class IntField(Field):
def __init__(self, db_column=""):
self._value = None # 表的数据
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():
# 把attrs中与数据库表字段有关的列提取出来
if isinstance(val, Field):
fields[key] = val # value 直接走描述器__get__()
_meta = {}
db_table = name.lower() # 数据表名称默认取小写类名称
_meta['db_table'] = db_table
attrs['_meta'] = _meta
attrs['_fields'] = fields
# 以上过程相当于对类进行了修改
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)] 等价于 字典的键值对
# ['='.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