如何确保子类具有与基类相同的初始化程序?

How to make sure a subclass has the same initialiser as the baseclass?

基本上,我试图定义一个符合 RFC UUID scheme 的子 class 字符串。这个class的对象只有符合8-4-4-4-12十六进制字符串才能存在,否则不存在。所以我需要在初始化期间检查它,但不确定如何考虑 str.

的所有可能的初始化参数

我的代码是这样的:

import uuid

class UniversalID(str):
    def __init__(self, val:str):
        super().__init__()
        try:
            uuid.UUID(hex=val)
            self=val
        except ValueError as inv_str:
            logging.error(msg=f'Invalid id queried {val}')
            raise inv_str

sample= uuid.uuid1().hex
isinstance(UniversalID(sample), str) # Shows true, as expected

但不确定这是否是正确的方法,因为 str 初始化程序可能还有其他我没有处理的参数。

这个问题可以概括为,如果我想修改 __init__ 方法并在子 class 中进行一些验证检查,我是否需要完全访问基中的初始化程序class,以确保它接受相同的参数并以相同的方式处理?更糟糕的是,我是否必须复制粘贴代码?

您可能想要创建一个继承自 uuid.UUID 的实例,并在将参数传递给您自己的构造函数之前对传递给您自己的构造函数的参数进行检查。

正如我在评论中所说,您必须在其 __new__() 方法中设置不可变类型(如字符串)的值。我找不到适合您的规范来源或示例 — 我是从很久以前读过的一些书中了解到的,所以决定为您编一个(根据您的代码):

import logging
import uuid


class UniversalID(str):
    # You don't really need to define this, because it's what would happen anyway.
    def __new__(cls, *args, **kwargs):
        return super().__new__(cls, *args, **kwargs)

    def __init__(self, *args, **kwargs):
        try:
            uuid.UUID(hex=self)
        except ValueError as inv_str:
            logging.error(msg=f'Invalid id queried {self}')
            raise inv_str


if __name__ == '__main__':

    sample1 = uuid.uuid1().hex
    try:
        isinstance(UniversalID(sample1), str)
    except ValueError as exc:
        print(f'ERROR: {exc} {sample1=!r}')
    else:
        print(f'{sample1=!r} is a valid hex uuid.')

    print()
    sample2 = 'not a hex uuid'
    try:
        isinstance(UniversalID(sample2), str)
    except ValueError as exc:
        print(f'ERROR: {exc} {sample2=!r}')
    else:
        print(f'{sample2=!r} is a valid hex uuid.')