面向对象反射、内置方法、元类、属性查找作业

1、在元类中控制把自定义类的数据属性都变成大写

class Mymeta(type):
    def __new__(cls,x,y,z):#其中x为类名,y为基类,z为名称空间
        class_dic = {}
        for k,v in z.items():
            if not callable(v) and not k.startswith('__'):
                class_dic[k.upper()] = v
            else:
                class_dic[k] = v
        return type.__new__(cls,x,y,class_dic)


class People(metaclass = Mymeta):
    country = 'China'
    tag = '龙的传人'
    def __init__(self,name,age):
        self.name = name
        self.age = age

​    def say(self):
​        print('<%s:%s>'%(self.name,self.age))

print(People.__dict__)

2、在元类中控制自定义的类无需__init__方法

1)元类帮其完成创建对象,以及初始化操作;

2)要求实例化时传参必须为关键字形式,否则抛出异常TypeError: must use keyword argument

3)key作为用户自定义类产生对象的属性,且所有属性变成大写

class Mymeta(type):
    def __call__(cls,*args,**kwargs):
        if len(args):
            raise TypeError('must use keyword argument')
        obj = object.__new__(cls)
        for k,v in kwargs.items():
            obj.__dict__[k.upper()] = v
        return obj

class People(metaclass = Mymeta):

​    country = 'China'
​    tag = '龙的传人'
​    def singing(self):
​        print('[{}]正在唱: 万里长城永不倒。。。'.format(self.NAME))

tank = People(name = 'tank', age = 18)
print(tank.__dict__)
tank.singing()

3、在元类中控制自定义的类产生的对象相关的属性全部为隐藏属性

class Mymeta(type):
    def __call__(self,*args,**kwargs):
        people_obj = object.__new__(self)
        self.__init__(people_obj,*args,**kwargs)
        people_obj.__dict__={
        '_%s__%s'%(self.__name__,k):v for k,v in people_obj.__dict__.items()
        }
        return people_obj

class People(metaclass = Mymeta):
    country = 'China'
    tag = '龙的传人'
    def __init__(self,name,age):
        self.name = name
        self.age = age
    def singing(self):
        print('[{}]正在唱:万里长城永不倒。。。'.format(self._People__name))

tank = People('tank',84)
tank.singing()
print(tank.tag)

4、基于元类实现单例模式

import settings

class Mymeta(type):
    def __init__(self,name,bases,dic):
        self.__instance = object.__new__(self)
        self.__init__(self.__instance,settings.HOST,settings.PORT)
        super().__init__(name,bases,dic)

​    def __call__(self,*args,**kwargs):
​        if args or kwargs:
​            obj = object.__new__(self)
​            self.__init__(obj,*args,**kwargs)
​            return obj
​        return self.__instance


class Mysql(metaclass=Mymeta):
    def __init__(self,host,port):
        self.host = host
        self.port = port

obj1 = Mysql()
obj2 = Mysql()
obj3 = Mysql()
print(obj1 is obj2 is obj3)

猜你喜欢

转载自www.cnblogs.com/leilijian/p/12709868.html
今日推荐