元类 metaclass

2021-01-07 17:31

阅读:490

class ObjectCreator(object):
    pass

my_object = ObjectCreator()
print my_object
#输出:<__main__.objectcreator object at>

 类同样也是一种对象。只要你使用关键字class,Python解释器在执行的时候就会创建一个对象。下面的代码段:

class ObjectCreator(object):
     pass

将在内存中创建一个对象,名字就是ObjectCreator。这个对象(类)自身拥有创建对象(类实例)的能力,而这就是为什么它是一个类的原因。但是,它的本质仍然是一个对象,于是你可以对它做如下的操作:
你可以将它赋值给一个变量,

你可以拷贝它,

你可以为它增加属性,

你可以将它作为函数参数进行传递。

 

3.type创建元类--------所有的类都是type创建的对象:原理

# 元类
print(type(1))  # 
print(type(int))  # 
print(type(type)) #  元类的类型就是它自己

 

原型:type(类名,基类元组(可以为空,用于继承), 包含属性或函数的字典)

 以下两种写法都可以:

type(‘Classname‘,(object,),dict(hello=fun()))

type(‘Classname‘,(object,),{"hello":fun()})

1、class 自定义的类名称

2、(object,)是继承类,的元组,如果只有一个就写这种形势(object,);多个(object,xxxx,)

3、dict(hello=fun()) 或 {"hello":fun()} 第三个参数,是一个字典等号左是 自定义的方法名,右侧是已写好的方法名,这个要注意,有参数且没有默认值的情况下,要加括号;

# 如何使用元类创建类
def __init__(self, name, age):
    self.name = name
    self.age = age


def sing(self,song):
    print(f"{self.name} is sing {song} !")


# 所有类都是type创建的对象
stu = type("Student", (object,), {     # 当你 class ClassName 底层就是用type实现类的创建过程
    "__init__": __init__,
    "sing": sing
})

if __name__ == __main__:
    # 使用类创建对象
    obj = MyClass()
    # 元类创建类
    # stu 相当于接收Student类; stu()实例化类;stu().name方法,调用的其实是我们定义的__ini__()构造方法(fun)。
    print(stu)  # 
    print(stu("goge", 18)) # <__main__.student object at>
    s = stu("zhangsan", 20)
    print(s.name)  # zhangsan
    print(s.age)  # 20
    print(s.sing("夜曲"))  # zhangsan is sing 夜曲 !

int,list....等类都是由元类创建的,首字母小写了。

同理,有非object类的继承,直接继承写在元组里即可(object要删除掉)。object也是由type创建的。是默认的最顶层的类,即强制默认从object继承

 

4.实际应用中创建元类:继承type

# 继承type创建元类
class MyMetaClass(type):

    def func(self):
        print("func is running...")

    def __new__(cls, name: str, bases: tuple, attr: dict):
        # __new__创建对象(重写定义了创建对象的过程)
        """
        创建对象(这个对象是一个类)
        :param name: 字符串,类的名称
        :param bases: 元组(基础类1,基础类2,...)
        :param attr: 字典(__dict__属性)
        """
        name = "Person"
        attr["name"] = "zhangsan"
        attr["age"] = 19
        attr["func"] = cls.func
        attr["add"] = lambda self,a,b: a+b
        bases = (object,)
        return type.__new__(cls, name,bases, attr)

# metaclass 指定类是由谁创建的
# 所有类,如果不指定metaclass,默认metaclass是type
# 自定义某个元类,通常是从type创建的
class MyClass(object, metaclass=MyMetaClass): # 不指定metaclass,默认metaclass=type
    pass

if __name__ == __main__:
    print(MyClass.__bases__)  # (,)
    print(MyClass.__name__)  # Person
    print(MyClass.__dict__)  #  {‘__module__‘: ‘__main__‘, ‘name‘: ‘zhangsan‘, ‘age‘: 19, ‘func‘: , ‘add‘: . at 0x000001AAC24664C8>, ‘__dict__‘: , ‘__weakref__‘: , ‘__doc__‘: None}
    print(MyClass.func)   #  
    print(MyClass.add)   # . at 0x000001

 

 

 

 

 

 

 

 

 


评论


亲,登录后才可以留言!