python面向对象之元类

元类

元类(A) ---> 类(B) ---> 实例(C)

对于实例C而言,它是对象,它的类就是类B

对于类B而言,它其实也是对象,那它的类就是元类A

对于元类A而言,它其实也是对象,那它的类就是自己本身

造类

第一阶段

class Foo:
    count = 0
    def __init__(self,name):
        self.name = name
    def eat(self):
        print("eat")
    def run(self):
        print("run")

# ------------------------------------------

class_name = "Foo"		# 类名
class_bases = (object,)	# 继承类
class_body = """		
count = 0
def __init__(self,name):
    self.name = name
def eat(self):
    print("eat")
def run(self):
    print("run")
"""
class_dict = dict()		# dict属性和方法
exec(class_body,{},class_dict)	# 将class_bady中的字符串,转化为键值对存储到class_dict中
one = type(class_name,class_bases,class_dict)	# 使用type创建类

print(one)
print(Foo)
<class '__main__.Foo'>
<class '__main__.Foo'>

这时,我们发现通过type创建出来一个和Foo相同的类one,但是这里的变量太死板了,我们还需要改变一下

第二阶段

class  Foo(type):
    def __init__(self,class_name,class_bases,class_dict):
        if not class_dict.get("__doc__"):
            raise  TypeError("请加上注释")
        super().__init__(class_name,class_bases,class_dict)


class person(object,metaclass=Foo):
    
    def __init__(self,name,age,sex):
        self.name = name
        self.age = age
        self.sex = sex

    def run(self):
        print("run")

    def eat(self):
        print("eat")


one = person('plf',18,'男')
print(one.name)
print(one.age)
print(one.sex)
Traceback (most recent call last):
  File "E:/***/***/***/test1.py", line 15, in <module>
    class person(object, metaclass=Foo):
  File "E:/***/***/***/test1.py", line 11, in __init__
    raise TypeError("请加上注释")
TypeError: 请加上注释

因为我们在Foo类的__init__方法中对创建类的条件做了一些逻辑处理(如果类中没有注释,直接抛异常),解决的办法:第九行加上注释即可

class  Foo(type):
    def __init__(self,class_name,class_bases,class_dict):
        if not class_dict.get("__doc__"):
            raise  TypeError("请加上注释")
        super().__init__(class_name,class_bases,class_dict)


class person(object,metaclass=Foo):
    '''我加上注释了'''
    def __init__(self,name,age,sex):
        self.name = name
        self.age = age
        self.sex = sex

    def run(self):
        print("run")

    def eat(self):
        print("eat")

总结:元类创建类,主要__init__方法中增加逻辑

造对象

NAME = 'PLF'
AGE = 18
class Foo(type):
    def __init__(self,class_name,class_bases,class_dict):
        self.count = 1
        super().__init__(class_name,class_bases,class_dict)

    def __call__(self, *args, **kwargs):
        # 造空类
        obj = object.__new__(self)
        # 造对象
        if  len(args) == 0 and len(kwargs) == 0:
            self.__init__(obj,NAME,AGE)
            return obj
        self.__init__(obj,*args,**kwargs)
        return  obj

class Person(object,metaclass=Foo):
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def run(self):
        print("run")

    def eat(self):
        print("eat")

    def __call__(self, *args, **kwargs):
        print("调用了")
        # return self

one = Person('zhangsan',1000)
print('one对象的name:',one.name)
print('one对象的age:',one.age)

ori = Person()
print('ori对象的name:',ori.name)
print('ori对象的name:',ori.age)
one对象的name: zhangsan
one对象的age: 1000
ori对象的name: PLF
ori对象的name: 18

总结:通过元类造对象,操作的逻辑可以在__call__方法或者__new__方法中进行

原文地址:https://www.cnblogs.com/plf-Jack/p/11066400.html