1.元类
元类,就是创建类的创建者,简单来说就是代码的生成器
python元类都是从type类继承的。用元类可以做一些很麻烦的工作,如验证子类,注册子类等。
2.注册序列化类实例
import json
# global dict
registry = {}
def register_class(target_class):
registry[target_class.__name__] = target_class
class Serializable(object):
def __init__(self, *args):
self.args = args
def serialize(self):
return json.dumps({
'class':self.__class__.__name__,
'args':self.args
})
class Meta(type):
def __new__(meta, name, bases, class_dict):
cls = type.__new__(meta, name, bases, class_dict)
register_class(cls)
return cls
class Serialize(Serializable, metaclass=Meta):
pass
def Deserialize(data):
params = json.loads(data)
name = params['class']
target_class = registry[name]
s = target_class(*params['args'])
return s
# test class
class vec2d(Serialize):
def __init__(self, x, y):
super().__init__(x,y)
self.x, self.y = x, y
def __repr__(self):
return 'vec2d(%d,%d)' % (self.x, self.y)
if __name__=='__main__':
t = vec2d(3,-12)
print('before', t)
data = t.serialize()
print("serialized:"+data)
m = Deserialize(data)
print("deserialized:" , m)
结果:
before vec2d(3,-12)
serialized:{"class": "vec2d", "args": [3, -12]}
deserialized: vec2d(3,-12)
3.元类构造相同结构的属性实例,多用在数据库操作
元类可以用在类定义好,未使用时,修改类的属性,与描述符搭配起来,更方便。
class Fild(object):
'''
数据库中的列
'''
def __init__(self):
self.name = None
self.internal_name = None
def __get__(self, instance, owner):
if instance is None:
return self
return getattr(instance, self.internal_name, "")
def __set__(self, instance, value):
setattr(instance, self.internal_name, value)
class Meta(type):
def __new__(meta, name, bases, class_dict):
for key,value in class_dict.items():
if isinstance(value, Fild):
value.name = key
value.internal_name = "_" + key
cls = type.__new__(meta, name, bases, class_dict)
return cls
class DatabaseRow(object, metaclass=Meta):
'''
构造一系列有相同结构的属性值
'''
pass
class customer(DatabaseRow):
first_name = Fild()
last_name = Fild()
if __name__=='__main__':
foo = customer()
print('befor:', repr(foo.first_name), foo.__dict__)
foo.first_name = 'Killer'
print('after:', repr(foo.first_name), foo.__dict__)
结果:
befor: '' {}
after: 'Killer' {'_first_name': 'Killer'}
参考: