Python自定义类的实现方式(元类)

本文详细介绍了元类在Python中的使用,通过函数和类两种方式实现元类,用于自定义类的创建,修改类的属性。元类主要用于拦截类的创建、修改类并返回。虽然元类通常被认为是高级特性,但了解其工作原理对于深入Python编程至关重要。
摘要由CSDN通过智能技术生成

一,使用函数实现

def upper_attr(class_name, class_parents, class_attr):
    new_attr = {}
    for name, value in class_attr.items():
        if not name.startswith('__'):
            new_attr[name.upper()] = value  # 将属性名转为大写后返回给创建的类

    return type(class_name, class_parents, new_attr)  # 返回创建好的类,type是固定这些参数

# metaclass的定义如果使用函数自定义一个类的实现,如果是函数则调用函数实现,如果是类,则实例化类实现
# 第一种使用函数实现
class Foo(object, metaclass=upper_attr):  
    bar = 'pop'


f = Foo()
print(f.BAR)  #返回的类中属性名已被被处理为大写

二,使用类实现

class UpAttrMetaClass(type):  # 这里必须继承与type,否则报错:
    # metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases
    # 元类冲突:派生类的元类必须是其所有基元类的(非严格)子类, 即元类必须是基类的子类,基类自是type
    def __new__(cls, class_name, class_parent, class_attr):
        new_attr = {}
        for name, value in class_attr.items():
            if not name.startswith('__'):
                new_attr[name.upper()] = value
        # 1, return type(class_name, class_parent, new_attr)
        # 2, return type.__new__(cls, class_name, class_parent, new_attr) 调用父类的__new__方法
        # return super().__new__(cls, class_name, class_parent, new_attr) 调用父类的__new__方法
        return super(UpAttrMetaClass, cls).__new__(cls, class_name, class_parent, new_attr)  # 兼容py2


class Foo(object, metaclass=UpAttrMetaClass):  # 当使用一个类来自定义生成类(作为元类),会实例化这个类来实现,所以改写类的__new__方法即可
    bar = 'pop'

# -- tips ---
# __new__ 是在__init__之前被调用的特殊方法
# __new__是用来创建对象并返回之的方法
# 而__init__只是用来将传入的参数初始化给对象
# 你很少用到__new__,除非你希望能够控制对象的创建
# 这里,创建的对象是类,我们希望能够自定义它,所以我们这里改写__new__
# 如果你希望的话,你也可以在__init__中做些事情

f = Foo()
print(f.BAR)

基于想要达到的目的(自定义类的创建),元类的主要作用是:

  1. 拦截类的创建
  2. 修改类
  3. 返回修改之后的类

究竟为什么要使用元类?

一般来说,用不上它:

“元类就是深度的魔法,99%的用户应该根本不必为此操心。如果你想搞清楚究竟是否需要用到元类,那么你就不需要它。那些实际用到元类的人都非常清楚地知道他们需要做什么,而且根本不需要解释为什么要用元类。” —— Python界的领袖 Tim Peters

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值