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

class Mymetaclass(type):
    def __new__(cls, name, bases, attrs):
        update_attrs = {}
        for k, v in attrs.items():
            if not callable(v) and not k.startswith('__'):
                update_attrs[k.upper()] = v
            else:
                update_attrs[k] = v
        return type.__new__(cls, name, bases, update_attrs)


class Chinese(metaclass=Mymetaclass):
    country = 'China'
    tag = 'Legend of the Dragon'

    def walk(self):
        print('%s is walking' % self.name)


print(Chinese.__dict__)
'''
{'__module__': '__main__',
 'COUNTRY': 'China', 
 'TAG': 'Legend of the Dragon',
 'walk': <function Chinese.walk at 0x0000000001E7B950>,
 '__dict__': <attribute '__dict__' of 'Chinese' objects>,                                         
 '__weakref__': <attribute '__weakref__' of 'Chinese' objects>,
 '__doc__': None}
'''

 

# 2、在元类中控制自定义的类无需__init__方法
# 2.1.元类帮其完成创建对象,以及初始化操作;
# 2.2.要求实例化时传参必须为关键字形式,否则抛出异常TypeError: must use keyword argument
# 2.3.key作为用户自定义类产生对象的属性,且所有属性变成大写

class Mymetaclass(type):
    # def __new__(cls,name,bases,attrs):
    #     update_attrs={}
    #     for k,v in attrs.items():
    #         if not callable(v) and not k.startswith('__'):
    #             update_attrs[k.upper()]=v
    #         else:
    #             update_attrs[k]=v
    #     return type.__new__(cls,name,bases,update_attrs)

    def __call__(self, *args, **kwargs):
        if args:
            raise TypeError('must use keyword argument for key function')
        obj = object.__new__(self)  # 创建对象,self为类Foo

        for k, v in kwargs.items():
            obj.__dict__[k.upper()] = v
        return obj


class Chinese(metaclass=Mymetaclass):
    country = 'China'
    tag = 'Legend of the Dragon'  # 龙的传人

    def walk(self):
        print('%s is walking' % self.name)


p = Chinese(name='lili', age=18, sex='male')
print(p.__dict__)

 

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

class Mymeta(type):
    def __init__(self, class_name, class_bases, class_dic):
        # 控制类Foo的创建
        super(Mymeta, self).__init__(class_name, class_bases, class_dic)

    def __call__(self, *args, **kwargs):
        # 控制Foo的调用过程,即Foo对象的产生过程
        obj = self.__new__(self)
        self.__init__(obj, *args, **kwargs)
        obj.__dict__ = {'_%s__%s' % (self.__name__, k): v for k, v in obj.__dict__.items()}

        return obj


class Foo(object, metaclass=Mymeta):  # Foo=Mymeta(...)
    def __init__(self, name, age, sex):
        self.name = name
        self.age = age
        self.sex = sex


obj = Foo('lili', 18, 'male')
print(obj.__dict__)

 

4、基于元类实现单例模式:老湿链接 https://zhuanlan.zhihu.com/p/109336845

 

posted on 2020-02-02 11:01  焚音留香  阅读(182)  评论(0编辑  收藏  举报