metaclass-元类

  • metaclass 就是一个用来创建其他 class 的类
  • type 类就是所有 class 默认的 metaclass
  • 可以在定义类时,声明 metaclass
1
2
3
4
5
6
7
8
9
10
11
class Car(type):
@staticmethod
def __new__(mcs, *args):
class_ = super().__new__(mcs, *args)
class_.auto = True
return class_

class Porsche(object, metaclass=Car):
pass

print(Porsche.auto)
  • 依据传入的关键字参数,对属性进行扩展
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Car(type):
@staticmethod
def __new__(mcs, *args, **kwargs):
class_ = super().__new__(mcs, *args)
if kwargs:
for key, value in kwargs.items():
setattr(class_, key, value)
return class_

class Porsche(object, metaclass=Car, auto = True, origin = "Germany"):
pass

print(Porsche.auto)
print(Porsche.origin)
  • 在元类中获取使用了元类的类的属性
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
class PropUtil:
def __init__(self,attr):
self._attr = f"_{attr}" # 避免递归调用

def get(self,obj):
if not hasattr(obj, self._attr):
return None
return getattr(obj, self._attr)

def set(self,obj,value):
setattr(obj,self._attr, value)

class Car(type):
@staticmethod
def __new__(mcs, *args, **kwargs):
class_ = super().__new__(mcs, *args)
for attr in class_.attrs:
prop = PropUtil(attr)
pObj = property(fget=prop.get, fset=prop.set)
setattr(class_, attr, pObj)
return class_

class Porsche(object, metaclass=Car):
attrs = ["origin", "auto"]

panamera = Porsche()
print(panamera.auto)
panamera.auto = True
print(panamera.auto)

# 使用装饰器实现
def car(cls):
return Car(cls.__name__, cls.__bases__, dict(cls.__dict__))

@car
class Benz:
attrs = ["origin", "auto"]

benz = Benz()
print(benz.auto)
print(benz.origin)
benz.auto = False
print(benz.auto)

更新: 2024-01-10 00:47:48
原文: https://www.yuque.com/zacharyblock/cx2om6/ed59q8lf72v6ibfn