Python课程设计 第 27 / 52 篇

类的宿主-参考答案

PS:这一章代码必须要在类的创建过程,调用过程和单例模式的分支语句添加注释,其他注释也可自由添加

  1. 详细说一下自定类的创建过程和调用过程
  2. 除了文中讲到的方法之外,另外用至少4种方式实现单例模式(有能力还可以使用更多种)
# 第一种:元类
class SingletonType(type):

    def __init__(cls, *args, **kwargs):
        cls.__instance = None
        super().__init__(*args, **kwargs)

    def __call__(cls, *args, **kwargs):
        if cls.__instance is None:
            # 如果 __instance 不存在,创建新的实例
            cls.__instance = super().__call__(*args, **kwargs)
            return cls.__instance
        else:
            # 如果存在,直接返回
            return cls.__instance

class Spam(metaclass=SingletonType):

    def __init__(self):
        print('Creating Spam')

a = Spam()
b = Spam()

print(a is b)  # 这里输出为 True

# 第二种:__new__
class Singleton(object):
    __instance = None

    def __new__(cls, *args, **kw):
        if not cls.__instance:
            cls.__instance = super().__new__(cls, *args, **kw)
        return cls.__instance

class Foo(Singleton):
    a = 1

one = Foo()
two = Foo()
print(one is two)

# 第三种:装饰器
def create_singleton(cls):
    __instance = {}

    def inner():
        if cls not in __instance:
            __instance[cls] = cls()
        return __instance[cls]

    return inner

@create_singleton
class Singleton1(object):
    def __init__(self):
        pass

st1 = Singleton1()
st2 = Singleton1()
print(st1 is st2)

# 第四种:模块
# 同目录下另外一个文件名为st.py  内容如下
class Singleton(object):
    pass

singleton = Singleton()
########################
import st

# singleton1 = st.Singleton()
singleton1 = st.singleton
singleton2 = st.singleton
print(singleton1 is singleton2)
  1. 程序设计,自定义轿车元类CarMeta,实现元类为CarMeta的类至少有生产日期(production_date)、发动机编号(engine_number)及载客量(capacity)三个基本属性,没有就不行
"""
程序设计,自定义轿车元类CarMeta,
实现元类为CarMeta的类至少有生产日期(production_date)、
发动机编号(engine_number)及载客量(capacity)三个基本属性,没有就不行
"""

class CarType(type):
    # # 这两行代码可以不用写,因为是完全重复的,视频讲解中有,但也不影响
    # def __init__(cls, class_name, class_bases, class_dict):
    #    super().__init__(class_name, class_bases, class_dict)

    def __call__(cls, *args, **kwargs):
        obj = object.__new__(cls)
        cls.__init__(obj, *args, **kwargs)
        print(dir(obj))  # 对象的属性列表
        if 'production_date' in dir(obj) and \
                'engine_number' in dir(obj) and \
                'capacity' in dir(obj):
            return obj
        else:
            raise TypeError('缺少production_date,engine_number或者capacity属性')

# # 这段代码缺少capacity属性会报错
# class Car(metaclass=CarType):
#     def __init__(self, name, production_date, engine_number):
#         self.name = name
#         self.production_date = production_date
#         self.engine_number = engine_number
# 
# 
# car = Car('红旗HS7', '2019.9.3', 9527)

class Car(metaclass=CarType):
    def __init__(self, name, production_date, engine_number, capacity):
        self.name = name
        self.production_date = production_date
        self.engine_number = engine_number
        self.capacity = capacity

car = Car('红旗HS7', '2019.9.3', 9527, 5)