上一篇文章: Python==与is对比
下一篇文章: Python是动态语言:动态编辑属性、动态编辑方法本篇内容只供了解,实际上99%的python程序员都用不到元类哟,不过你要想成为那1%,请随意享用,别客气😆python
元类做用:拦截类的建立、修改类、返回修改以后的类程序员
万物皆对象,类建立了实例对象,那既然万物皆对象,类也是对象,那什么建立了类呢,啦啦啦,固然就是本篇的主人翁:元类。编程
既然类也是一个对象,那就应该具备对象共有的特性:能够将其赋给变量segmentfault
能够拷贝函数
能够增长属性指针
能够做为函数参数进行传递code
实例:对象
class A: def hello_fun(self): print("Hello World") def test(a): print("类做为函数参数传递:",a) #类也是对象,因此能够打印 print(A) #由于类也是对象,因此能够做为函数参数进行传递 test(A) #hasattr用来判断指定类中是有有对应属性 print(hasattr(A,"mark"))#哼,我就是一个属性,来打我呀 #添加属性而且赋值 A.mark="帅"#mark是属性名称,帅是值 print(hasattr(A,"mark")) print("mark属性值:",A.mark) #由于类是一个对象,因此能够拷贝 B=A#拷贝 print(B)
运行结果:继承
<class '__main__.A'> 类做为函数参数传递: <class '__main__.A'> False True mark属性值: 帅 <class '__main__.A'>
既然类也是对象,固然能够动态建立,好比在函数内部建立。
实例:内存
def test(): class A: def hello_fun(self): print("Hello World") print("函数内部建立的类:",A) test()
运行结果:
函数内部建立的类: <class '__main__.test.<locals>.A'>
type函数除了能够检查类型外,另外一个高大上的用途就是动态建立类。语法:type(类名,由父类名称组成的元组(能够为空),包含属性的字典(名称和值))
实例:
#定义一个没有方法,没有属性的类:A A=type("A",(),{}) #打印A print(A) #打印A的实例 print(A()) print("*"*30) #定义一个带两个属性的类:B B=type("B",(),{"name":"mark","age":18}) print(B.name) print(B.age) print("*"*30) #定义一个带普通方法的类:C def test_for_c(self): print(self.name) C=type("C",(),{"name":"mark","age":18,"test_for_c":test_for_c}) c=C() c.test_for_c() print("*"*30) #添加静态方法 @staticmethod def static_method_test(): print("static method test") D=type("D",(),{"name":"mark","age":18,"static_method_test":static_method_test}) D.static_method_test() print("*"*30) #添加类方法 @classmethod def class_method_test(cls): print(cls.name) E=type("E",(),{"name":"mark","age":18,"class_method_test":class_method_test}) e=E() e.class_method_test() E.class_method_test()
结果:
<class '__main__.A'> <__main__.A object at 0x10b7ac0f0> ****************************** mark 18 ****************************** mark ****************************** static method test ****************************** mark mark
实例:
class A(object,metaclass=xxxx): pass
滴答滴答,想象一下,解析指针如今运行到这个类的上面,此处类还没加载到内存中,而后开始解析A,首先去A的定义中找,有没有指定__metaclass__属性,若是指定了,就利用这个指定的属性来建立类,没有指定就会用type开生成类。具体步骤以下:
如今自定义一个元类,保证全部的属性名都大写
实例:
def upper_attr(class_name,class_parent,class_attr): #遍历属性字典,把不是__开头的属性名称都编程大写 newAttr={} for name,value in class_attr.items(): if not name.startswith("__"): newAttr[name.upper()]=value #调用type来建立类 return type(class_name,class_parent,newAttr) class A(object,metaclass=upper_attr): mark="帅哥" print(hasattr(A,"mark")) print(hasattr(A,"MARK")) print(A.MARK)
结果:
False True 帅哥
如今自定义一个元类,保证全部的属性名都大写
实例:
class UpperAttrMetaClass(type): #__new__是在__init__以前被调用的特殊方法,用来建立对象并返回, #而__init__只是将传递的参数赋给对象 def __new__(cls,class_name,class_parent,class_attr): # 遍历属性字典,把不是__开头的属性名称都编程大写 newAttr = {} for name, value in class_attr.items(): if not name.startswith("__"): newAttr[name.upper()] = value # 方法1:调用type来建立类 #return type(class_name, class_parent, newAttr) #方法2:复用type.__new__方法 #return type.__new__(cls,class_name,class_parent,newAttr) #方法3:使用super方法 return super(UpperAttrMetaClass,cls).__new__(cls,class_name,class_parent,newAttr) class A(object,metaclass=UpperAttrMetaClass): mark="帅哥" print(hasattr(A,"mark")) print(hasattr(A,"MARK")) print(A.MARK)
结果:
False True 帅哥