李宁老师已经在「极客起源」 微信公众号推出《Python编程思想》电子书,囊括了Python的核心技术,以及Python的主要函数库的使用方法。读者可以在「极客起源」 公众号中输入 160442 开始学习。
如果希望创建某一批类全部具有某种特征,则可以通过 metaclass来实现。使用 metaclass可以在创建类时动态修改类定义。为了使用 metaclass动态修改类定义,程序需要先定义 metaclass, metaclass应该继承type类,并重写new()方法。
下面程序定义了一个 metaclass类。
示例代码:metaclass_demo. py
# 定义MyMetaClass,继承type
class MyMetaClass(type):
# cls代表动态修改的类
# name代表动态修改的类名
# bases代表被动态修改的类的所有父类
# attr代表被动态修改的类的所有属性、方法组成的字典
def __new__(cls, name, bases, attrs):
# 动态为该类添加一个cal_price方法
attrs['cal_price'] = lambda self: self.price * self.discount # 折扣价
return type.__new__(cls, name, bases, attrs)
# 定义House类
class House(metaclass=MyMetaClass):
__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
h = House("河畔小区", 2000000)
h.discount = 0.89
# 创建House对象的discount()方法
print(h.cal_price())
class Book(metaclass=MyMetaClass):
__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
b = Book("Python从菜鸟到高手", 128)
b.discount = 0.6
print(b.cal_price())
在这段代码中定义了House和Book两个类,在定义这两个类时都指定了 metaclass属性,因此当 Python解释器在创建这两个类时,MyMetaClass的new方法就会被调用,用于修改这两个类MyMetaClass类的new方法会为目标类动态添加 cal_price方法,因此,虽然在定义House和Book类时没有定义 cal_price方法,但这两个类依然有 cal_price方法。运行这段代码,会输出如下的内容:
1780000.0
76.8
从上面的输出结果来看,通过使用 metaclass可以动态修改程序中的一批类,对它们集中进行某种修改。这个功能在开发一些基础性框架时非常有用,程序可以通过使用 metaclass为某一批需要具有通用功能的类添加属性和方法。
-----------------支持作者请转发本文,也可以加李宁老师微信:unitymarvel,或扫描下面二维码加微信--------
欢迎关注 极客起源 微信公众号,更多精彩视频和文章等着你哦!