PYthon-4.15作业

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

class MyDef(type):
    def __new__(cls, class_name, class_attr, class_dic):
        upper_data = {}
        for k,v in class_dic.items():
            if not callable(v) and not k.startswith('__'):
                upper_data[k.upper()] = v
            else:
                upper_data[k] = v
        return type.__new__(cls, class_name, class_attr, upper_data)

class People(metaclass=MyDef):
    time = 'now'
    work = 'weekends'

print(People.__dict__)

 

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

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

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

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

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

class People(metaclass=MyDef):
    tag = 'China'
    some = 'None'

p1 = People(name = 'panda')
print(p1.__dict__)

 

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

class Mymeta(type):
    def __init__(self, class_name, class_bases, attr):
        super(Mymeta, self).__init__(class_name, class_bases, attr)

    def __call__(self, *args, **kwargs):
        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 P(metaclass=Mymeta):
    def __init__(self, name, age):
        self.name = name
        self.age = age
p1 = P('123','567')
print(p1._P__name)

 

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

# settings.py文件
IP = '1.1.1.1'
PORT = 3303


 方式一:定义一个类方法实现单例模式

import settings

class People:
    __instance = None    #用于保存实例化的状态

    def __init__(self, ip, port):
        self.ip = ip
        self.port = port

    @classmethod
    def get(cls):
        if cls.__instance is None:
            cls.__instance = cls(settings.IP, settings.PORT)
        return cls.__instance


obj1 = People.get()
obj2 = People.get()
print(obj1)
print(obj2)
# <__main__.People object at 0x00000000021BA9B0>
# <__main__.People object at 0x00000000021BA9B0>




#方式二:定义一个装饰器实现单例模式
import settings

def singlet(cls):
    _instance = cls(settings.IP, settings.PORT)   #先实例化一个对象

    def wrapper(*args, **kwargs):
        if args or kwargs:
            obj = cls(*args, **kwargs)
            return obj        #有参数是返回后来实例化对象
        return _instance         #无参时,返回已经实例化好的对象

    return wrapper


@singlet    # MySQL=wrapper(MySQL)
class MySQL:

    def __init__(self, ip, port):
        self.ip = ip
        self.port = port


# 没有参数时,单例模式
obj1 = MySQL()
obj2 = MySQL()
obj3 = MySQL()
obj4 = MySQL('1.1.1.1', 3303)
print(obj1)
print(obj2)
print(obj3)
print(obj4)
# <__main__.MySQL object at 0x0000000001E6AA90>
# <__main__.MySQL object at 0x0000000001E6AA90>
# <__main__.MySQL object at 0x0000000001E6AA90>
# <__main__.MySQL object at 0x0000000001E6AB00>


#方式三:定制元类实现单例模式
import settings

class Mymeta(type):
    def __init__(self, class_name, class_bases, class_dic):
        instance = self(settings.IP, settings.PORT)
        self.__instance = instance

    def __call__(self, *args, **kwargs):         # self=MySQL
        if args or kwargs:          #  有参数执行下面的代码
            obj = self.__new__(self)          #创造一个空对象
            self.__init__(obj, *args, **kwargs)          #初始化
            return obj             #返回对象
        return self.__instance


class MySQL(metaclass=Mymeta):
    def __init__(self, ip, port):
        self.ip = ip
        self.port = port


obj1 = MySQL()
obj2 = MySQL()
obj3 = MySQL()
obj4 = MySQL('1.2.3.1', 3305)
print(obj1)
print(obj2)
print(obj3)
print(obj4)
# <__main__.MySQL object at 0x00000000021BAA90>
# <__main__.MySQL object at 0x00000000021BAA90>
# <__main__.MySQL object at 0x00000000021BAA90>
# <__main__.MySQL object at 0x00000000021BAB00>


方式四:利用模块导入实现单例模式
# singleton模块
import settings


class MySQL:
    def __init__(self, ip, port):
        self.ip = ip
        self.port = port


instance = MySQL(settings.IP, settings.PORT)

#单例模块
def f1():
    from singleton import instance
    print(instance)


def f2():
    from singleton import instance, MySQL
    print(instance)
    obj = MySQL('1111', 3302)
    print(obj)


f1()
f2()

# <singleton.MySQL object at 0x00000000021FAA90>
# <singleton.MySQL object at 0x00000000021FAA90>
# <singleton.MySQL object at 0x00000000021FA358>
原文地址:https://www.cnblogs.com/lijunc/p/12708161.html