Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/299.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python中没有抽象方法的抽象数据类:禁止实例化_Python_Python 3.x_Oop_Abc_Python Dataclasses - Fatal编程技术网

Python中没有抽象方法的抽象数据类:禁止实例化

Python中没有抽象方法的抽象数据类:禁止实例化,python,python-3.x,oop,abc,python-dataclasses,Python,Python 3.x,Oop,Abc,Python Dataclasses,即使一个类是从ABC继承的,看起来它仍然可以被实例化,除非它包含抽象方法 有了下面的代码,防止创建标识符对象的最佳方法是什么:标识符(['get','Name']) 如果这个问题已经得到回答,我提前道歉。这似乎很基本,然而,出于某种原因,我找不到答案 干杯,Hlib。我找到的最简单的方法是在\uuu post\u init\uuuu方法中检查对象的类型: @dataclass class Identifier(ABC): ... def __post_init__(self):

即使一个类是从
ABC
继承的,看起来它仍然可以被实例化,除非它包含抽象方法

有了下面的代码,防止创建
标识符
对象的最佳方法是什么:
标识符(['get','Name'])

如果这个问题已经得到回答,我提前道歉。这似乎很基本,然而,出于某种原因,我找不到答案


干杯,Hlib。

我找到的最简单的方法是在
\uuu post\u init\uuuu
方法中检查对象的类型:

@dataclass
class Identifier(ABC):
    ...

    def __post_init__(self):
        if self.__class__ == Identifier:
            raise TypeError("Cannot instantiate abstract class.")

    ...

您可以创建一个保证这种行为的
AbstractDataclass
类,并且每次遇到您描述的情况时都可以使用它

@dataclass 
class AbstractDataclass(ABC): 
    def __new__(cls, *args, **kwargs): 
        if cls == AbstractDataclass or cls.__bases__[0] == AbstractDataclass: 
            raise TypeError("Cannot instantiate abstract class.") 
        return super().__new__(cls)
因此,如果
Identifier
继承自
AbstractDataclass
,而不是直接继承自
ABC
,则无需修改
\uuuu post\uu init\uuuu

@dataclass
class Identifier(AbstractDataclass):
    sub_tokens: List[str]

    @staticmethod
    def from_sub_tokens(sub_tokens):
        return SimpleIdentifier(sub_tokens) if len(sub_tokens) == 1 else CompoundIdentifier(sub_tokens)


@dataclass
class SimpleIdentifier(Identifier):
    pass


@dataclass
class CompoundIdentifier(Identifier):
    pass
实例化
Identifier
将引发
TypeError
,但不会实例化
SimpleIdentifier
compountifier
。 而且,
AbstractDataclass
可以在代码的其他部分重复使用

@dataclass
class Identifier(AbstractDataclass):
    sub_tokens: List[str]

    @staticmethod
    def from_sub_tokens(sub_tokens):
        return SimpleIdentifier(sub_tokens) if len(sub_tokens) == 1 else CompoundIdentifier(sub_tokens)


@dataclass
class SimpleIdentifier(Identifier):
    pass


@dataclass
class CompoundIdentifier(Identifier):
    pass