3月16日学习内容整理:metaclass

本文深入探讨了Python中元类的概念及其实现方式,包括如何使用type创建类、自定义元类以及不同版本间的区别。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、首先我们要知道:

对象是由类创建的,而类是由type类创建的

所以创建类有两个方法:

class Foo(object):
    pass

# 类名,继承关系,属性
Foo = type('Foo',(object,),{})

上面第一种方法也是默认用type来创建类的,我们就可以理解为类其实就是type的一个对象

当类名()这样加括号的时候,会首先调用type的_ _call_ _方法,在这个方法里会调用类的_ _new_ _方法来创建一个裸着的对象,也就是开辟内存空间,但是没有任何东西,继而继续调用执行类的_ _init_ _方法来给对象封装一些属性

补充一下:对象()这样加括号就会调用类的_ _call_ _方法

 

2、metaclass就可以指定我们自定义的type类,当用类名()时就会从我们定义的metaclass参数值的类中调用_ _call_ _方法,要依次调用_ _new_ _和_ _init_ _方法,返回对象

这样做的一个好处是我们在实例对象时先是_ _new_ _方法再是_ _init_ _方法,用了我们自定义type类的时候我们就可以在new方法和init方法之间就可以做一些操作了

class MyType(type):
    def __init__(self,*args,**kwargs):
        super(MyType,self).__init__(*args,**kwargs)

    def __call__(self, *args, **kwargs):
        obj = self.__new__(self,*args, **kwargs) # object.__init__(....)
        obj.__init__(*args, **kwargs)
        # self.__init__(obj,*args, **kwargs)
        return obj

class Foo(object,metaclass=MyType):
    def __init__(self):
        print('xxx')

# 1. 类是MyType的对象。由MyType(...)
# 2. Foo()
obj = Foo()
print(obj)

 

注意在python2中metaclass的写法不同:

# python3
class Foo(object,metaclass=MyType):
    pass 
        
# python2
class Foo(object):
    __metaclass__ = MyType

 

 

补充:

metaclass的作用:就是用来指定当前类由谁创建,对派生类也是一样的,也就是当父类指定了metaclass以后,它的派生类也得由metaclass指定的类来创建

 

第二种指定metaclass类的方法

class MyType(type):
    def __init__(self, *args, **kwargs):
        super(MyType, self).__init__(*args, **kwargs)

    def __call__(cls, *args, **kwargs):
        print('xxxx')
        return super(MyType, cls).__call__(*args, **kwargs)

# Foo继承的类是由MyType创建的,所以Foo类继承这个创建出来的类,那Foo的metaclass也是MyType
class Foo(MyType('Base', (object,), {})):
    pass
obj = Foo()

 

第三种指定metaclass类的方法

class MyType(type):
    def __init__(self, *args, **kwargs):
        super(MyType, self).__init__(*args, **kwargs)

    def __call__(cls, *args, **kwargs):
        return super(MyType, cls).__call__(*args, **kwargs)


def with_metaclass(base):
    return MyType('XX', (base,), {})

# Foo继承的是with_metaclass函数的返回值,返回值仍是由MyType创建的一个类
# 所以Foo作为创建出来的类的派生类,Foo的metaclass也是MyType
class Foo(with_metaclass(object)):
    pass

 

 

总结:类和对象加括号时的流程

类是type创建的,所以说类就是type的一个对象,而type又是由object创建的

我们创建类的时候实际上就是写type(),那这样的话就会调用object的__call__方法,在这个方法中会调用type的__new__和__init___方法

我们实例类对象时就是写类(),那这样的话就会调用type的__call__方法,在这个方法中会调用类的__new__和__init__方法

转载于:https://www.cnblogs.com/wanghl1011/articles/8584186.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值