python3 之metaclass

python

如果希望创建某一批类全部具有某种特征,则可通过 metaclass 来实现。使用 metaclass 可以在创建类时动态修改类定义。

为了使用 metaclass 动态修改类定义,程序需要先定义 metaclass, metaclass 应该继承 type 类,并重写 __new__() 方法。

下面程序定义了一个 metaclass 类:

#定义ItemMetaClass,继承type

class ItemMetaClass(type):

# cls 代表动态修改的类

# name 代表动态修改的类名

# bases 代表被动态修改的类的所有父类

# attrs 代表被动态修改的类的所有属性、方法组成的字典

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

#动态为该类添加一个cal_price方法

attrs['cal_price'] = lambda self:self.price * self._discount

return type.__new__(cls, name, bases, attrs)

上面程序定义了一个 ItemMetaClass 类,该类继承了 type 类,并重写了 __new__ 方法,在重写该方法时为目标类动态添加了一个 cal_price 方法。

metaclass 类的 __new__ 方法的作用是:当程序使用 class 定义新类时,如果指定了 metaclass,那么 metaclass 的 __new__ 方法就会被自动执行。

例如,如下程序使用 metaclass 定义了两个类:

#定义book类

class Book(metaclass=ItemMetaClass):

__slots__ = ('name', 'price', '_discount')

def __init__(self, name, price):

self.name = name

self.price = price

@property

def discount(self):

return self._discount

@discount.setter

def discount(self, discount):

self._discount = discount

#定义cellPhone类

class CellPhone(metaclass=ItemMetaClass):

__slots__ = ('price', '_discount')

def __init__(self, price):

self.price = price

@property

def discount(self):

return self._discount

@discount.setter

def discount(self, discount):

self._discount = discount

  

上面程序定义了 Book 和 CellPhone 两个类,在定义这两个类时都指定了 metaclass 信息,因此当 Python 解释器在创建这两个类时,ItemMetaClass 的 __new__ 方法就会被调用,用于修改这两个类。

ItemMetaClass 类的 __new__ 方法会为目标类动态添加 cal_price 方法,因此,虽然在定义 Book、CellPhone 类时没有定义 cal_price() 方法,但这两个类依然有 cal_price() 方法。如下程序测试了 Book、CellPhone 两个类的 cal_price() 方法: 

#Book类实例化

b = Book('Python基础教程', 89)

b.discount = 0.8

#Book类的cal_price()方法

print(b.cal_price())

#CellPhone类实例化

cp = CellPhone(2300)

cp.discount = 0.85

#CellPhone类的cel_price方法

print(cp.cal_price())

  

输出结果如下:

71.2

1955.0

  

  

以上是 python3 之metaclass 的全部内容, 来源链接: utcz.com/z/388181.html

回到顶部