python元类

引子:

  理解python的元类,要明白python一切皆对象

代码:

# -*- coding: utf-8 -*-
"""
@author:yuan_x
@software:PyCharm
@file:meta_class_stu2.py
@time:2021/3/6 10:43 上午


"""

"""
metaclass  作用
            用来指定 当前类 由谁创建 若不指定 默认用type创建
            
下方例子:
    1 在定义 bar 的时候 会先调用 metaclass类也就是foo的 __new__  __init 但这时候 生成的 是bar 这个类 而不是bar的实例
    2 在 bar()实例的时候 才会去调用 metaclass的 __call__
正常情况下 父类无法操纵子类 但是 只有元类可以
在python中所有定义的类 都是type类的实例


在python 中另类定义 方法
class = type(classname, superclasses, attributedict)
这里 就是调用type的__call__运算符重载 并且会进一步调用
type.__new__(typeclass, classname, superclasses, attributedict)
type.__init__(class, classname, superclasses, attributedict)


"""


class foo(type):

    def __new__(cls, *args, **kwargs):
        """
        本质上如果 当前类被指定成 metaclass 则 先创建自己
        """
        # print(*args)
        # print(**kwargs)
        print("in  foo new cls.__name__", cls.__name__)
        a = type.__new__(cls, *args, **kwargs)
        print("in  foo new a", a)
        return a

    def __init__(self, *args, **kwargs):

        print("in  foo init self.__name__11", self.__name__)
        super(foo, self).__init__(*args, **kwargs)

    def __call__(cls, *args, **kwargs):
        """
        本质上 调用当前类的__new__ 在调用类的__init__方法 将self替换成cls

        """
        print("in foo call",cls.__name__)
        # call_obj=super(foo, cls).__call__(*args, **kwargs)
        call_obj=cls.__new__(cls)
        cls.__init__(cls,*args,**kwargs)
        print("call",call_obj)
        return call_obj



class bar(metaclass=foo):
    """

    若此类本身或者父类继承了metaclass 则必须要用metaclass 来创建
    """

    def __init__(self):
        print("in bar init")

    def __new__(cls, *args, **kwargs):
        print("__bar new")
        return object.__new__(cls)


# 其实通过上述 
# metaclass 的 __new__ __init__是用来控制类的生成的
# __call__是用来控制 类的实例生成的 因为在__call__中可以控制子类的__new__  __init__
# bar()

# bar_cls=foo('barobj',(object,),{})
# print(bar_cls)

# class bast(bar):
#     """
#     bast 继承了bar  所以会调用metaclass来创建
#     """
#     pass


#obj = bar
# obj2=bast()


"""
类由type来创建
class foo(metaclass=type):
    pass
    
继承type 
class foo(type):
    pass

"""


class foo(object):
    pass

#print(type(foo))
#
#
# # obj 这个实例对象 是类 foo创建
# obj = foo()
#
# # foo这个类是由type创建的 python 里一切皆对象
# foo1 = type('foo1', (object,), {})

  

posted @ 2021-05-11 22:01  Yuan_x  阅读(72)  评论(0编辑  收藏  举报