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)