python3元类_Python3 元类(metaclass)

1. 类也是对象赋值给一个变量

可以作为参数进行传递

可以动态增加它的属性

可以拷贝

class ObjectClass(object):

pass

valObj = ObjectClass # 可以赋值

obj1 = ObjectClass()

obj2 = valObj()

print(obj1, obj2)

def testfunc(obj): # 可以作为参数传递

return obj()

obj3 = testfunc(ObjectClass)

print(obj3)

print(hasattr(ObjectClass, 'new_attr'))

ObjectClass.new_attr = 'Megvii' # 可以动态的增加属性

print(hasattr(ObjectClass, 'new_attr'))

import copy

ObjcetC_C = copy.copy(ObjectClass) # 可以拷贝

print(ObjcetC_C)

print(ObjcetC_C is ObjectClass)

False

True

True

那么就有一个问题了:既然 类本身是一个对象,那这个对象是谁创建的????

obj4 = ObjectClass()

print(obj4)

大概我们都知道这句话干了什么:将一个类(ObjectClass)实例化(创建一个对象)的过程。 那么也就是说,class关键字会在Python解释器解释到这里的时候创建一个对象(ObjectClass),而这个对象,拥有一个其他的一般对象没有的能力: 创建一个新的对象。

2. type 这个类

print(type('hello world'))

print(type(123456))

print(type(obj4))

我们会用 type() 来查看一个对象的类型,这是我们最常见的用法

newObject = type('newObject', (), {})

print(newObject)

obj5 = newObject()

print(obj5)

到这里,我们知道了这些东西:类是一个对象

type 可以创建类

type 创建的对象拥有创建对象的能力(也就是类)

type 就是 Python 中所有类的元类(metaclass)

3. metaclass

元类 并不是某一个类的名字,它是一个概念,是一种Python的思想。

def MetaClass(name, bases, attrs):

attrs['Author']='Megvii'

return type(name, bases, attrs)

class InsClass(object, metaclass=MetaClass):

Imethod='InsClass'

def __init__(self, param):

self.__param = param

obj6 = InsClass('test_instance')

print(obj6.Author)

print(dir(obj6))

Megvii

['Author', 'Imethod', '_InsClass__param', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__']

元类 metaclass 就是用来创建一个对象的,如果我们自定义元类,就可以将创建对象的过程拦截下来,从而对这个对象进行自定义。

道生一,一生二,二生三,三生万物

道是 type 一是 metaclass 二是类 三是对象 对象就是 Python 的所有

3.How && When

Singleton mode

class Singleton(type):

def __init__(self, *args, **kwargs):

self.__instance = None

super().__init__(*args, **kwargs)

def __call__(self, *args, **kwargs):

if self.__instance is None:

self.__instance = super().__call__(*args, **kwargs)

return self.__instance

else:

return self.__instance

class Foo(metaclass=Singleton):

def __init__(self):

self.author = 'Megvii'

foo1=Foo()

foo2=Foo()

print(foo1 is foo2)

foo1.author = 'MEGVII'

print(foo2.author)

True

MEGVII

4. ORM (Object Relational Mapping)

首先定义 Field 类,它是所有 Fields 的父类

class Field(object):

def __init__(self, name, col_type):

self.name = name

self.col_type = col_type

def __str__(self):

return "".format(self.__class__.__name__, self.name)

派生出其他的 Field 类型,假定只有 CharField(字符串类型) 和 IntegerField(整数类型) 两种

class CharField(Field):

def __init__(self, name, col_type='varchar(100)'):

super(CharField, self).__init__(name, col_type)

class IntegerField(Field):

def __init__(self, name, col_type='bigint'):

super(IntegerField, self).__init__(name, col_type)

自定义元类,控制 Model 的创建过程

class ModelMetaClass(type):

def __new__(cls, name, bases, attrs):

if name == 'Model':

return super(ModelMetaClass, cls).__new__(cls, name, bases, attrs)

mappings = dict()

for key, val in attrs.items():

if isinstance(val, Field):

mappings[key] = val

for key in mappings.keys():

attrs.pop(key) # 防止字段污染类属性本身

attrs['__table__'] = name # 保存表名为类名

attrs['__mappings__'] = mappings # 添加映射关系

return super(ModelMetaClass, cls).__new__(cls, name, bases, attrs)

定义 Model 类,作为所有 Model 的父类

class Model(dict, metaclass=ModelMetaClass): # 本质是一个自定义的 dict 类

def __init__(self, **kwargs):

super(Model, self).__init__(**kwargs)

def __getattr__(self, key):

try:

return self[key]

except Exception:

raise AttributeError("'Model' object has no attribute {0}".format(key))

def __setattr__(self, key, value):

self[key] = value

def sql_(self):

fields = []

args = []

for k, v in self.__mappings__.items():

fields.append(v.name)

args.append(getattr(self, k, None))

return "INSERT INTO {table} ({fi}) VALUES ({va})".format(

table=self.__table__,

fi=', '.join(fields),

va=', '.join(args)

)

def save(self):

return self.sql_()

class User(Model):

uid = IntegerField('uid')

name = CharField('name')

user = User(uid='102740', name='zhangbo')

print(user.save())

print(dir(user))

INSERT INTO User (uid, name) VALUES (102740, zhangbo)

['__class__', '__contains__', '__delattr__', '__delitem__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattr__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mappings__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', '__table__', '__weakref__', 'clear', 'copy', 'fromkeys', 'get', 'items', 'keys', 'pop', 'popitem', 'save', 'setdefault', 'sql_', 'update', 'values']

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值