码迷,mamicode.com
首页 > Web开发 > 详细

元类 metaclass

时间:2021-01-07 12:13:56      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:ret   cal   turn   直接   拷贝   oge   add   __new__   metaclass   

二、元类metaclass

实例对象是由类来创建,那么类又是由什么来创建的呢? 答案就是元类

1.类的类型:是元类

元类创建类,类创建对象。

# 元类
print(type(1))  # <class ‘int‘>
print(type(int))  # <class ‘type‘>

 

2.理解python中的类也是对象

Python中类的概念借鉴于Smalltalk,这显得有些奇特。在大多数编程语言中,类就是一组用来描述如何生成一个对象的代码段。在Python中这一点仍然成立。

class ObjectCreator(object):
    pass

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

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

class ObjectCreator(object):
     pass

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

你可以拷贝它,

你可以为它增加属性,

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

 

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

# 元类
print(type(1))  # <class ‘int‘>
print(type(int))  # <class ‘type‘>
print(type(type)) # <class ‘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)  # <class ‘__main__.Student‘>
    print(stu("goge", 18)) # <__main__.Student object at 0x00000253C153FE88>
    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__)  # (<class ‘object‘>,)
    print(MyClass.__name__)  # Person
    print(MyClass.__dict__)  #  {‘__module__‘: ‘__main__‘, ‘name‘: ‘zhangsan‘, ‘age‘: 19, ‘func‘: <function MyMetaClass.func at 0x000001AAC24663A8>, ‘add‘: <function MyMetaClass.__new__.<locals>.<lambda> at 0x000001AAC24664C8>, ‘__dict__‘: <attribute ‘__dict__‘ of ‘Person‘ objects>, ‘__weakref__‘: <attribute ‘__weakref__‘ of ‘Person‘ objects>, ‘__doc__‘: None}
    print(MyClass.func)   #  <function MyMetaClass.func at 0x000001AAC24663A8>
    print(MyClass.add)   # <function MyMetaClass.__new__.<locals>.<lambda> at 0x000001

 

 

 

 

 

 

 

 

 

元类 metaclass

标签:ret   cal   turn   直接   拷贝   oge   add   __new__   metaclass   

原文地址:https://www.cnblogs.com/ananmy/p/14233218.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!