标签: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
标签:ret cal turn 直接 拷贝 oge add __new__ metaclass
原文地址:https://www.cnblogs.com/ananmy/p/14233218.html