python中的元类以及反射

一,元类

元类也是类,它是用来创建类的类

在默认情况下所有元类都是type

只要是继承了type 那么这个类就变成了一个元类。

自定义元类:

class MyType(type):
    def __init__(self,clss_name,bases,dict):
        super().__init__(clss_name,bases,dict)
        print(clss_name,bases,dict)
        if not clss_name.istitle():
            raise Exception("你丫的 类名不会写...")

# 为pig类指定了元类为MyType
class Pig(metaclass=MyType):
    pass

class Duck(metaclass=MyType):
    pass

二,元类中的call方法:

当你调用类对象时会自动执行元类中的__call__方法,并将这个类本身作为第一个参数传入。
覆盖元类中的call之后,这个类就无法产生对象,必须用super().__call__ 来完成对象创建,而且还要返回值

使用场景:

当想要控制对象的创建过程时,就会覆盖call方法。

当想要控制类的创建过程时,就会覆盖init 方法。

实现将对象的所有属性名称转为大写:4

lass MyType(type):
    def __call__(self, *args, **kwargs):
        new_args = []
        for a in args:
            new_args.append(a.upper())

        print(new_args)
        print(kwargs)
        return super().__call__(*new_args,**kwargs)


class Person(metaclass=MyType):
    def __init__(self,name,gender):
        self.name = name
        self.gender = gender

p = Person(name="jack",gender="woman")
print(p.name)
print(p.gender)

2.new 方法

当创建类对象时,会首先执行元类中的__new__方法,并拿到一个空对象,然后会自动调用__init__

初始化方法。

如果覆盖了这个方法,那new方法必须要有返回值,而且返回值必须是类对象

class Meta(type):

    def __new__(cls, *args, **kwargs):
        print(cls) # 元类自己
        print(args) # 创建类需要的几个参数  类名,基类,名称空间
        print(kwargs) #空的 
        print("new run")
        # return super().__new__(cls,*args,**kwargs)
        obj = type.__new__(cls,*args,**kwargs)
        return obj
    def __init__(self,a,b,c):
        super().__init__(a,b,c)
        print("init run")
class A(metaclass=Meta):
    pass
print(A)

3.单例:

指的是一个类产生一个对象

单例是为了节省资源,当一个类的所有对象属性全部相同时,就没必要创建多个对象

元类实现:

# 单例n元类
class Single(type):
def __call__(self, *args, **kwargs):
if hasattr(self,"obj"): #判断是否存在已经有的对象
return getattr(self,"obj") # 有就返回

obj = super().__call__(*args,**kwargs) # 没有则创建
print("new 了")
self.obj = obj # 并存入类中
return obj


class Student(metaclass=Single):
def __init__(self,name):
self.name = name


class Person(metaclass=Single):
pass

# 只会创建一个对象
Person()
Person()

 

 

 

三,反射

反射指的是一个对象应该具备,可以检测,修改,增加自身属性的能力

反射其实就是通过字符串操作属性

1.hasattr:判断某个对象的某个属性是否存在

2.getattr:从某个对象中取出某个属性

3.setattr:给某个对象添加某个属性

4.delattr:从某个对象中删除某个属性

 

posted on 2019-07-31 14:36  IT界的蜉蝣  阅读(242)  评论(0编辑  收藏  举报

导航