首页 > 解决方案 > 为每个类类型自动生成唯一 ID

问题描述

我有一个有趣的问题。我想编写一个类,它在继承时为所有子类提供以下行为:

现在,有趣的部分是:我希望上面的机制能够工作,而不管用于实例化此类的路径如何。让我们假设以下内容:

from .Package.Class1 import Class1
from TopPackage.Package.Class1 import Class1

from .Package.Class2 import Class2
from TopPackage.Package.Class2 import Class2

在这两种情况下,我都希望 Class1 在两种导入样式中生成相同的 self.id 值。我还希望 Class2 从 Class1 生成不同的 self.id 值,但在它自己的导入样式之间是相同的。

到目前为止,我为类 1 和 2 将继承自的类编写了以下代码:

class ClassWithId(ABC):
    _EXISTING_OBJECT_IDS = dict()

    def __init__(self):
        if self in ClassWithId._EXISTING_OBJECT_IDS.keys():
            self.id = ClassWithId._EXISTING_OBJECT_IDS[self]
        else:
            self.id = uuid.uuid4()
            ClassWithId[self] = self.id

但是,我在这里有一些问题:

有任何想法吗?

更新:我已将 Elrond 的建议集成到我的代码中,但是不同的导入级别(按包)会为同一类产生不同的 UUID 值:

<class 'StageTwo.Steps.SsTestHandler1.SsTestHandler1'>   3583c89c-5ba8-4b28-a909-31cc27628370
<class 'tests.TestStages.StageTwo.Steps.SsTestHandler1.SsTestHandler1'>   f4ead4a0-f5f7-4d95-8252-0de47104cb2f

<class 'StageTwo.Steps.SsTestHandler2.SsTestHandler2'>   8bd9a774-0110-4eee-a30c-a4263ad546cf
<class 'tests.TestStages.StageTwo.Steps.SsTestHandler2.SsTestHandler2'>   773d84c4-82a3-4684-92b5-51509e6db545

也许我忘了提,但是我的 ClassWithId 是由 ClassX 和 ClassY 继承的,而且是这两个类,预计可以抵抗我上面显示的情况(以不同的路径导入,但仍然保留相同的 UUID)。

标签: pythonpython-3.xoop

解决方案


为此,您需要使用 a metaclass

import uuid
import abc

class BaseMeta(abc.ABCMeta):
    def __new__(mcs, name, bases, attrs):
        attrs['_class_uuid'] = uuid.uuid4()
        return super().__new__(mcs, name, bases, attrs)     

class Base(metaclass=BaseMeta):
    def __init__(self):
        print(self.__class__.__name__, self._class_uuid)

现在,所有继承自的类都Base将通过该_class_uuid属性分配一个 uuid,每个子类一次:

from package1.class1 import Class1
from package2.class2 import Class2

Class1() # 6e0852c8-61c9-4f8b-9817-eeeda4b49d56
Class1() # 6e0852c8-61c9-4f8b-9817-eeeda4b49d56

Class2() # 73012f1a-a984-4f76-96f1-ef5225a38fbe
Class2() # 73012f1a-a984-4f76-96f1-ef5225a38fbe

在任何一种情况下,使用绝对/相对导入都不应该有所作为。


推荐阅读