python高级之元类

04-10 阅读 0评论

python高级之元类


python高级之元类

  • 一、Type创建类
    • 1、传统方式创建类
    • 2、非传统方式
    • 二、元类
    • 三、总结

      一、Type创建类

      class A(object):
          def __init__(self, name):
              self.name = name
          def __new__(cls, *args, **kwargs):
              data = object.__new__(cls)
              return data
      

      根据类创建对象

      obj=A(‘kobe’)

      1、执行类的new方法,创建对象(空对象),【构造方法】 {}

      2、执行类的init方法,初始化对象 ,【初始化方法】 {‘name’:‘kobe’}

      对象是基于类创建出来的;问题:类是由谁创建的?

      类默认是由type创建的

      1、传统方式创建类

      class A(object):
          v1 = 123
          def func(self):
              return 666
      print(A)			#
      

      2、非传统方式

      类名

      继承类

      成员

      A1 = type('A', (object,), {"v1": 123, "func": lambda self: 666})
      print(A1)        #
      # 根据类创建对象
      obj1 = A1()			#
      print(obj1)
      # 调用对象中的func方法 
      print(obj1.func())  #666
      

      类默认由type创建,怎么让一个类的创建改为其他的东西呢? 元类。

      二、元类

      元类:指定类由谁来创建

      1、Foo类由MyType创建,代码如下

      class MyType(type):
          pass
      # Foo类由MyType创建
      class Foo(object, metaclass=MyType):
          pass
      

      2、假设Foo是一个对象,它是由MyType类创建。

      class MyType(type):
          def __init__(self, *args, **kwargs):
              print('init')
              super().__init__(*args, **kwargs)
          def __new__(cls, *args, **kwargs):
              # 创建类
              print('new')
              new_cls = super().__new__(cls, *args, **kwargs)
              print(new_cls)
              return new_cls
      # 假设Foo是一个对象,由MyType类创建。
      class Foo(object, metaclass=MyType):
          pass
      

      执行结果

      new
      
      init
      

      3、类加括号得到的是对象,执行的是__init__()和__new__()方法,对象加括号执行__call__()方法

      class F1(object):
          def __init__(self):
              print('init')
          # def __new__(cls, *args, **kwargs):
          #     print('new')
          def __call__(self, *args, **kwargs):
              print(111)
      # 类加括号得到的是对象,执行的是__init__和__new__方法
      obj = F1()
      # 对象加括号执行call方法
      obj()
      

      执行结果

      init
      111
      

      4、假设Foo是一个对象,由MyType创建。

      Foo类其实是MyType的一个对象。

      Foo() 加括号执行的是——》MyType类中的__call__()方法

      __call__()方法实现的功能是:

      1、调用自己那个类的__new__方法创建对象

      empty_object=self.__new__(self)

      2、调用你自己那个类__init__方法去初始化对象

      self.__init__(empty_object,*args,**kwargs)

      3、将创建的对象返回:return empty_object

      class MyType(type):
          def __init__(self, *args, **kwargs):
              print('init')
              super().__init__(*args, **kwargs)
          def __new__(cls, *args, **kwargs):
              # 创建类
              print('new')
              new_cls = super().__new__(cls, *args, **kwargs)
              print(new_cls)
              return new_cls
          def __call__(self, *args, **kwargs):
              # 1、调用自己哪个类的__new__方法创建对象
              empty_object=self.__new__(self)
              #2、调用你自己那个类 __init__方法去初始化
              self.__init__(empty_object,*args,**kwargs)
              return empty_object
      # 假设Foo是一个对象,由MyType创建。
      #  Foo类其实是MyType的一个对象。
      # Foo()  ——》MyType对象()
      class Foo(object, metaclass=MyType):
          def __init__(self,name):
              self.name=name
      v1=Foo('666')
      print(v1)
      print(v1.name)
      

      三、总结

      1、当我们不写MyType类时,Type中已经帮我们定义好了

      __init__

      __new__

      __call__ 方法了

      当我定义了MyType类时,

      __init__

      __new__

      __call__ 方法是我们自己定义的

      2、这就是为什么实例化对象的时候,先去创建对象再去初始化对象,Type类中已经实现了先 __new__()再__init__()

      python高级之元类

      3、代码从上到下执行,当执行到class Foo(object, metaclass=MyType)时

      先创建这个类,去MyType中的__new__()创建方法

      __init__()实例化方法,类在内存中创建好了,

      但是MyType中的__call__()方法是不执行的,因为类后面没有加括号

      如果类后面加了括号Foo(),会执行MyType的__call__()方法

      python高级之元类

      4、如果自己定义的类中实现了__call__方法,此时是不会执行的,因为Foo是MyType创建出来的

      python高级之元类

      5、如果要执行Foo类的__call__方法,需要实例化Foo类的对象v1,

      然后v1加括号

      python高级之元类


      python高级之元类


免责声明
本网站所收集的部分公开资料来源于AI生成和互联网,转载的目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。
文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。

发表评论

快捷回复: 表情:
评论列表 (暂无评论,人围观)

还没有评论,来说两句吧...

目录[+]