元类
所有的类或对象都是由元类(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()