zoukankan      html  css  js  c++  java
  • 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__方法中进行

  • 相关阅读:
    luogu P1833 樱花 看成混合背包
    luogu P1077 摆花 基础记数dp
    luogu P1095 守望者的逃离 经典dp
    Even Subset Sum Problem CodeForces
    Maximum White Subtree CodeForces
    Sleeping Schedule CodeForces
    Bombs CodeForces
    病毒侵袭持续中 HDU
    病毒侵袭 HDU
    Educational Codeforces Round 35 (Rated for Div. 2)
  • 原文地址:https://www.cnblogs.com/plf-Jack/p/11066400.html
Copyright © 2011-2022 走看看