• 作业24


    作业24

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

    class Mymeta(type):
        def __init__(self, class_name, class_base, class_dict):
            super().__init__(self)
            self.__name__ = class_name
            self.class_base = class_base
    
        def __new__(cls, class_name, class_base, class_dict):
            new_class_dict = {}
            for k, v in class_dict.items():
                if callable(v) or k.startswith("__"):
                    # if not isinstance(v,str) or k.startswith('__'):
                    new_class_dict[k] = v
                else:
                    new_class_dict[k.upper()] = v
            class_dict = new_class_dict
            return type.__new__(cls, class_name, class_base, class_dict)
    
        def __call__(self, *args, **kwargs):
            class_obj = self.__new__(self, *args, **kwargs)
            self.__init__(class_obj, *args, **kwargs)
            return class_obj
    
    
    class People(object,metaclass=Mymeta):
        flag = True
        msg = "fdsfsa"
    
        def __init__(self, name, age):
            self.name = name
            self.age = age
    
        def say(self):
            print(f"{self.name}---{self.age}")
    
        def __new__(cls, *args, **kwargs):
            return object.__new__(cls)
    
    
    print(People.__dict__)
    print(People.__bases__)
    print(People.class_base)
    print(People)
    print(People.__name__)
    

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

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

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

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

    class Mymeta(type):
        def __init__(self, class_name, class_base, class_dict):
            self.__name__ = class_name
            self.class_base = class_base
    
        def __new__(cls, class_name, class_base, class_dict):
            return type.__new__(cls, class_name, class_base, class_dict)
    
        def __call__(self, *args, **kwargs):
            class_obj = self.__new__(self, *args, **kwargs)
            if args:
                raise TypeError("不能传入位置参数must use keyword argument")
            for k,i in kwargs.items():
                class_obj.__dict__[k.upper()] = i
            return class_obj
    
    
    class People(object,metaclass=Mymeta):
        flag = True
        msg = "fdsfsa"
    
    
        # def say(self):
        #     print(f"{self.name}---{self.age}")
    
        def __new__(cls, *args, **kwargs):
            return object.__new__(cls)
    person1 = People(name = "wu",age=18)
    print(person1.NAME)
    

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

    
    
    
    
    
    class Mymeta(type):
        def __init__(self,class_name,class_base,class_dict):
            self.class_name = class_name
            self.class_base = class_base
            self.class_dict = class_dict
    
    
        def __new__(cls,*args, **kwargs):
            return type.__new__(cls,*args, **kwargs)
    
        def __call__(self, *args, **kwargs):
            class_obj = self.__new__(self,*args, **kwargs)
            self.__init__(class_obj,*args, **kwargs)
            new_dict = {}
            for k,v in kwargs.items():
                if not k.startswith("__"):
                    k = f"_{self.class_name}__{k}"
                    new_dict[k] = v
            class_obj.__dict__ = new_dict
            return class_obj
    
    
    class People(object,metaclass=Mymeta):
        flag = True
        msg = "fdsfsa"
        def __init__(self,name, age):
            self.name = name
            self.age = age
    
        def say(self):
            print(f"{self.name}---{self.age}")
    
        def __new__(cls, *args, **kwargs):
            return object.__new__(cls)
    person1 = People(name = "wu",age=18)
    print(person1.__dict__)
    
    
    
    
    

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

    单例:即单个实例,指的是同一个类实例化多次的结果指向同一个对象,用于节省内存空间

    如果我们从配置文件中读取配置来进行实例化,在配置相同的情况下,就没必要重复产生对象浪费内存了

    settings.py文件内容如下

    HOST='1.1.1.1'
    PORT=3306
    
    import settings
    class Mymeta(type):
        def __init__(self,*args,**kwargs):
            self.mysql_obj = object.__new__(self)
            self.__init__(self.mysql_obj,settings.HOST,settings.PORT)
            super().__init__(*args,**kwargs)
    
        def __call__(self, *args, **kwargs):
            if args or kwargs:
                obj = object.__new__(self)
                self.__init__(obj,*args,**kwargs)
                return obj
            return self.mysql_obj
    
    class Mysql(metaclass=Mymeta):
        def __init__(self,host,port):
            self.host=host
            self.port=port
    
    
    obj1=Mysql('1.1.1.2',3306)
    obj2=Mysql('1.1.1.3',3307)
    obj3 = Mysql()
    obj4 = Mysql()
    
    print(obj1 is obj2) #False
    print(obj3 is obj4) #False
    
  • 相关阅读:
    PHP环境搭建-修改密码
    先挖个坑....
    usaco 1.2.1(指针技巧)
    warfare(最大生成树裸题)
    最大生成树(最小生成树同理)
    快排
    简单邻接表代码实现
    并查集模板题
    并查集
    get 新技能
  • 原文地址:https://www.cnblogs.com/achai222/p/12709792.html
Copyright © 2020-2023  润新知