python - 通用单例的类型提示?

标签 python generics types singleton hint

我有一个基础服务,它为所有服务提供通用方法。此外,这个BaseService充当服务注册表:

class BaseService:
    instances = {}

    @classmethod
    def get_instance(cls) -> 'BaseService':
        if cls.instances.get(cls) is None:
            cls.instances[cls] = cls()
        return cls.instances[cls]

class Service1(BaseService):
    pass

class Service2(BaseService):
    pass

Service1.get_instance()
Service2.get_instance()
Service1.get_instance()

get_instance() 方法正在返回子类实例,我觉得当前注释 -> 'BaseService' 不正确。我应该如何正确注释这个方法?

最佳答案

正如我在评论中所说,为基类的类方法执行此操作是 这是有问题的,因为根据定义,该方法将与任何子类共享。对于单例来说尤其如此。

解决方法是为每个子类提供其自己的类似命名的方法,并带有正确的返回值注释。虽然这可以使用类装饰器来完成,如我答案的早期版本所示,但使用元类似乎是一种更干净的方法,因此我相应地更新了我的答案:

class BaseServiceMeta(type):
    """ Metaclass that properly annotates the return value of the get_instance() method of
        any subclasses of the BaseService class.
    """
    def __new__(metaclass, classname, bases, classdict):
        cls = super(metaclass, metaclass).__new__(metaclass, classname, bases, classdict)
        if classname != 'BaseService':  # subclass?

            # define function with the correct return value annotation
            def get_instance() -> classname:
                return super(cls, cls).get_instance()  # call superclass classmethod

            setattr(cls, 'get_instance', get_instance)  # override inherited method

        return cls

class BaseService(metaclass=BaseServiceMeta):  # metaclass added
    instances = {}

    @classmethod
    def get_instance(cls) -> 'BaseService':
        if cls.instances.get(cls) is None:
            cls.instances[cls] = cls()
        return cls.instances[cls]

class Service1(BaseService):
    pass

class Service2(BaseService):
    pass

# show that the methods have the correct return annotation
print(repr(BaseService.get_instance.__annotations__['return']))  # -> 'BaseService'
print(repr(   Service1.get_instance.__annotations__['return']))  # -> 'Service1'
print(repr(   Service2.get_instance.__annotations__['return']))  # -> 'Service2'

# call subclass methods to show they return the correct singleton instance of each type
print(Service1.get_instance())  # -> <__main__.Service1 object at 0x004A07D0>
print(Service2.get_instance())  # -> <__main__.Service2 object at 0x004A07F0>
print(Service1.get_instance())  # -> <__main__.Service1 object at 0x004A07D0>

关于python - 通用单例的类型提示?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43023405/

相关文章:

Python Pandas 减去每列并创建新列

python - 从 shell 设置 `ulimit -c`

java - 将不同类型的可比较数量与零进行比较

java - ArrayList 包含错误的类型对象,没有明确的原始类型转换

c - 为什么在printf中指定为整数的char被正确打印

java - properties.load() 如何接受非 inputStream

python - 将查询字符串传递给 ModelForm 隐藏字段 - Django

python - 合并 Pandas 数据框并根据条件删除重复行

java - 代码在 Eclipse 中编译但不通过命令提示符编译

sql - 自动递增表列