贰拾叁

Posted tangceng

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了贰拾叁相关的知识,希望对你有一定的参考价值。

一、元类

? 在python中一切皆对象,所以类也是一个对象,对象是由类实例化产生的,所以类也可以实例化产生。那么实例化产生类的类就是元类。

class B
    def __init__(self,v)
print(type(B))

<class 'type'>

? 使用print(type(类))的方法可以找到类的类。

? type为python内置元类,所有的类都是由type实例化产生的。

二、class底层原理分析

? 平时使用class + 类名的方式将类构造出来,但实际上这些类是由元类实例化产生的。type为python内置元类,类是由type实例化产生,并且传入一堆参数。

? type是使用类的内置__init__方法产生类的。

    # 类的源码
    def __init__(cls, what, bases=None, dict=None): # known special case of type.__init__
        """
        type(object_or_name, bases, dict)
        type(object) -> the object's type
        type(name, bases, dict) -> a new type
        # (copied from class doc)
        """
        pass

? 元类通过object_or_name, bases, dict(类名:字符串,父类,名称空间:字典)的方式产生类,可以代替class关键字的方式。

#通过type来直接产生类,不用class关键字了
l=
exec('''
school='oldboy'
def __init__(self,name):
    self.name=name
def score(self):
    print('分数是100')
''',,l)
def __init__(self,name):
    self.name=name

# Person=type('Person',(object,),'school':'oldboy','__init__':__init__)
#
Person=type('Person',(object,),l)

三、通过元类控制类的产生

? 通过控制类名,控制类的继承父类,控制类的名称空间的方法自定义元类,由此可以控制类的产生。

? 自定义元类,都要继承type元类。

class A(type):

class B(metaclass=  A):

? metaclass= A指定类B的元类为A。

? 练习:自定义元类,控制类产生,类的名称空间必须要有name字段才能创建成功,否则失败。

lass Mymeta(type):
    def __init__(self,name):
        if not 'name' in name:
            raise   TypeError('没有name字段')

class Aname(object,metaclass=Mymeta):
    def __init__(self,name):
        self.name = name

四、通过元类控制类的调用

? 通过元类控制类的调用实际上是在控制对象的产生。

class Mymeta(type):
    def __call__(self, *args, **kwargs):
        # print('xxx')

        return 1

class Person(object,metaclass=Mymeta):
    school='oldboy'
    def __init__(self,name):
        self.name=name
    def score(self):
        print('分数是100')

p=Person('nick')
print(p.name)

? 类的调用过程是先触发元类的__call__ ,再触发类的init方法。

? 练习:定义一个元类,定义一个类继承字典,使其具备点取值和赋值功能,通过元类控制对象的产生,把所有属性放在attr字典中,属性全删除。

class Mymeta(type):
    def __call__(self, *args, **kwargs):
        obj = self.__new__(self)
        obj.__init__(*args, **kwargs)
        dic = 
        dict.update(obj.__dict__)
        attr = 'attr':dic
        obj.__dict__.clear()
        obj.__dict__.update(attr)
        

class Test(dict,metaclass=Mymeta):
    def __init__(self,**kwargs):
        self.__dict__.update(kwargs)
    def __getattr__(self, item):
        return self.__dict__['attr'][item]
    def __setattr__(self, key, value):
        self.__dict__['attr'][key] = value
        t = Test(name='lqz', age=18)
print(t.__dict__)
print(t.name)
print(t.age)
t.male = 'nan'
print(t.male)
print(t.__dict__)

五、有元类后属性查找顺序

? 类的属性查找顺序:先从类本身中找--->mro继承关系去父类中找---->去自己定义的元类中找--->type中--->报错

? 对象的属性查找顺序:先从对象自身找--->类中找--->mro继承关系去父类中找--->报错

技术图片

以上是关于贰拾叁的主要内容,如果未能解决你的问题,请参考以下文章

java-6数组

数字金额转变成大写汉字金额

java动手动脑06

第七讲课后

数组及课后动手动脑

如何将人民币数字转为大写