所有的类或对象都是由元类(type)创建的
type(类名, 父类的元组(针对继承的情况,可以为空),包含属性的字典(名称和值))
class A:
set = 100
class Animal(A):
age = 10
def eat(self):
print("吃肉")
def run(self):
print("奔跑")
@classmethod
def update_age(cls):
cls.age += 1
@staticmethod
def print_info():
print("打印我所有的备注信息")
a = Animal()
print(help(a))
def hha():
print("111")
Text = type("Text", (Animal,), {"hha": hha}) # Text 类继承了Animal
print(help(Text))
1、构建Foo类
#构建目标代码
class Foo(object):
bar = True
#使用type构建
Foo = type('Foo', (), {'bar':True})
2.继承Foo类
#构建目标代码:
class FooChild(Foo):
pass
#使用type构建
FooChild = type('FooChild', (Foo,),{})
print FooChild
#输出:<class '__main__.FooChild'>
print FooChild.bar # bar属性是由Foo继承而来
#输出:True
3.为Foochild类增加方法
def echo_bar(self):
print self.bar
FooChild = type('FooChild', (Foo,), {'echo_bar': echo_bar})
hasattr(Foo, 'echo_bar')
#输出:False
hasattr(FooChild, 'echo_bar')
#输出:True
my_foo = FooChild()
my_foo.echo_bar()
#输出:True
可以看到,在Python中,类也是对象,你可以动态的创建类。这就是当我们使用关键字class时Python在幕后做的事情,而这就是通过元类来实现的。
class UpparAttrMetaClass(type):
def __new__(cls, class_name, class_parent, class_attr): # 重写父类的new方法
new_attr = dict()
for name,value in class_attr.items():
if not name.startswith("__"):
new_attr[name.upper()] = value
return type.__new__(cls,class_name,class_parent,new_attr)
class Foo(metaclass=UpparAttrMetaClass): # 你可以在写一个类的时候为其添加__metaclass__属性,定义了__metaclass__就定义了这个类的元类,类的元类可以是一个类,也可以是一个方法
bar = "zip"
# print(hasattr(Foo, 'bar'))
# print(hasattr(Foo, 'BAR'))
if hasattr(Foo, "BAR"):
f = Foo()
print(f.BAR)
# print("11111")
ORM框架的演变以及由来
class ModelMetaclass(type):
def __new__(cls, name, bases, attrs):
mappings = dict()
# 判断是否需要保存
for k, v in attrs.items():
# 判断是否是指定的StringField或者IntegerField的实例对象
if isinstance(v, tuple):
print('Found mapping: %s ==> %s' % (k, v))
mappings[k] = v
# 删除这些已经在字典中存储的属性
for k in mappings.keys():
attrs.pop(k)
# 将之前的uid/name/email/password以及对应的对象引用、类名字
attrs['__mappings__'] = mappings # 保存属性和列的映射关系
attrs['__table__'] = name # 假设表名和类名一致
return type.__new__(cls, name, bases, attrs)
class Model(object, metaclass=ModelMetaclass):
def __init__(self, **kwargs):
for name, value in kwargs.items():
setattr(self, name, value)
def save(self):
fields = []
args = []
for k, v in self.__mappings__.items():
fields.append(v[0])
args.append(getattr(self, k, None))
args_temp = list()
for temp in args:
# 判断入如果是数字类型
if isinstance(temp, int):
args_temp.append(str(temp))
elif isinstance(temp, str):
args_temp.append("""'%s'""" % temp)
sql = 'insert into %s (%s) values (%s)' % (self.__table__, ','.join(fields), ','.join(args_temp))
print('SQL: %s' % sql)
class User(Model):
uid = ('uid', "int unsigned")
name = ('username', "varchar(30)")
email = ('email', "varchar(30)")
password = ('password', "varchar(30)")
u = User(uid=12345, name='Michael', email='test@orm.org', password='my-pwd')
# print(u.__dict__)
u.save()