Python Basic -面向对象终极-metaclass、创建类,创建对象的过程,__new__()方法的基本原理,__call__()方法


Python中一切事物都是对象

metaclass,类的祖宗

如引言中所述,既然一切事物都是对象,所以类也是一个“对象”

问题:类这个“对象”是怎么生成的?

类这个对象其实是 “type” 这个父类创建的,可以查看一下type这个类

查看type类

class type(object):
    """
    type(object_or_name, bases, dict)
    type(object) -> the object's type
    type(name, bases, dict) -> a new type
    """
*******************省略****************************省略*********************************
    __itemsize__ = 40
    __mro__ = (
        None, # (!) forward: type, real value is "<class 'type'>"
        object,
    )
    __name__ = 'type'
    __qualname__ = 'type'
    __text_signature__ = None
    __weakrefoffset__ = 368

可以看到type类也是继承了object类的,那再接着看看object类

class object:
    """
    The base class of the class hierarchy.
    
    When called, it accepts no arguments and returns a new featureless
    instance that has no instance attributes and cannot be given any.
    """
    

object类是一个最顶层的基类,

小结

所以,平常我们创建的对象是写的类的实例,而写的类其实是type的对象。所以创建类有两种方式:

普通方式创建类

class Foo:
    def func(self):
        pass

特殊方式(通过type类的构造函数创建类)

def func(self):
    pass

foo = type("Foo",(object,),{"func":func})

# type 第一个参数:类名
# type 第二个参数:当前类的基类
# type 第三个参数:类的成员

type 第一个参数:类名
type 第二个参数:当前类的基类
type 第三个参数:类的成员

问题一:type类中如何实现创建类?

类中有一个属于 metaclass()” 用来表示该类由谁来实例化创建,所以,我们可以为__metaclass__ 设置一个type类的派生类,从而查看 类创建的过程


def function(self):
    print("function test")

foo = type("Foo",(object,),{"func":function})

# type 第一个参数:类名
# type 第二个参数:当前类的基类
# type 第三个参数:类的成员

foo 是类名,object是继承的这个类,func是成员类型,
object是一个超级的类,所有的类都会继承这个object的类,你不写他也继承。


自定义祖宗类

class MyType(type):
    def __init__(self,*args,**kwargs):
        print("123")
        pass
    def __call__(self, *args, **kwargs):
        print("456")


class Foo(object,metaclass=MyType):
    def func(self):
        print("Hello World")



obj = Foo()

"""
123
456
"""

如上,在继承时通过 metaclass= … 来定义这个类创建时的祖宗类来自于哪里。缺省情况下,创建类的时候会通过type这个类来创建,这里使用metaclass 指定通过哪个类来创建。

输出结果解析:

456:python一切皆对象,所以Foo其实是相当于是Mytype的对象(或者叫实例),再执行“Foo()”就会自动执行类里面的"call"方法,所以输出了“456”
123:123是类里面"init()“方法的内容,所以在通过类创建对象的时候会自动执行类里面的”“init()”" 所以进行了输出。

示例结论

本例主要是说明了可以通过metaclass 来指定祖宗类,如上示例所示,MyType就是手动创建的基类。

问题二:类又是如何创建对象?

注意上面所说的,通过类创建一个对象,然后“对象()” 会执行类的call方法。但是对象具体是怎么创建出来的呢?其实前面说过很多特殊方法,但是还有一个特殊方法是“new()”专用于通过类创建对象时自动执行的方法

简单的示例

class MyType(type):
    def __init__(self,*args,**kwargs):
        print("123")
        pass
    def __call__(self, *args, **kwargs):
        return self.__new__()

class Foo(object,metaclass=MyType):
    def __init__(self):
        pass
    @classmethod
    def __new__(cls, *args, **kwargs):
        return "object"

obj = Foo()
print(obj)
"""
123
object
"""

剖析代码运行流程

  • 第一步:代码从上至下运行到“class Foo(object,metaclass=MyType):”时,会自动执行“class MyType(type):”中的“init(self,*args,**kwargs)”方法,所以会打印一下“123”
  • 第二步:代码运行至 “obj = Foo()”时,因为“Foo”已经是个对象了,所以Foo() 会执行“MyType”中的__call__方法
  • 第三步:__call__方法,又返回"self.new()"方法,所以又转到“class Foo(object,metaclass=MyType):”中,返回object对象后,将返回值返回给obj对象。
class MyType(type):
    def __init__(self,what,bases=None,dict=None):
        super(MyType,self).__init__(what,bases,dict)
    def __call__(self, *args, **kwargs):
        obj = self.__new__(self,*args,**kwargs)
        self.__init__(obj)


class Foo(object,metaclass=MyType):
    def __init__(self,name):
        self.name = name

    @classmethod
    def __new__(cls, *args, **kwargs):
        return object.__new__(cls,*args,**kwargs)




obj = Foo()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值