魔法方法__类型

1.用过使用type的__new来控制类的名称空间

class Mymeta(type):
    def __init__(self,name,bases,dic):
        #self 是Person类,Person类中有名称空间之类的了
        print('1')
        # self.name='xxxxxxx'
    def __new__(cls, name,bases,dic): ##先执行__new__
        # print(name)
        # print(bases)
        # print(dic)
        #产生空对象(空类),在这里面生成的并不是空类,是有数据的类了
        #如何完成类的初始化,并且把name,bases,dic这些东西放入
        # return type.__new__(cls,name,bases,dic)
        print('2')
        dic2={'attr':{}}
        print(dic)
        for k,v in dic.items():
            #加入这一句,类名称空间中带__的就不会放到attr中
            if not k.startswith('__'):
                dic2['attr'][k]=v
        print('-------',dic2)
        return type.__new__(cls,name,bases,dic2)
class Person(metaclass=Mymeta):    
    school='oldboy'
    age=10
    def __init__(self,name,age):
        self.name=name
        self.age=age
print(Person.__dict__)
## {'attr': {'school': 'oldboy', 'age': 10}, '__module__': '__main__', '__dict__': <attribute '__dict__' of 'Person' objects>, '__weakref__': <attribute '__weakref__' of 'Person' objects>, '__doc__': None}

2.运用__init 来限制自定义类名

class Mymeta(type):
    def __init__(self, name, bases, dic):
        if 'name' not in dic:
            raise TypeError('怎么可以没有name字段')
class Penson(object,metaclass=Mymeta):
    def name(self):
        pass
p = Penson()

3.通过__call将对象的属性包到attr里并且可以用点方法取值赋值

class Mymeta(type):
    def __call__(self, *args, **kwargs):
        obj = Mydict.__new__(self)
        obj.attr = kwargs
        return obj
class Mydict(dict,metaclass=Mymeta):
    def __getattr__(self, item):
        return self.__dict__['attr'][item]
    def __setattr__(self, key, value):
        # print(self.__dict__)
        self.__dict__[key] = value
di = Mydict(name = 'nick',age = 18)
print(di)
print(di.age)
print(di.__dict__)
di.name = 'qwe'
print(di.name)

原文地址:https://www.cnblogs.com/oxtime/p/11461425.html