作业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
 posted on 2020-04-16 00:28  wwwpy  阅读(137)  评论(0编辑  收藏  举报