强制在子类python中实现特定属性

问题描述 投票:0回答:3

我有一个父类,我想“强制”从它继承的每个人都实现一些特定的类属性。

我的方法没有这个问题,因为我创建了一个虚拟方法来引发

NotImplementedError
,这使得它非常清楚。

至于类属性 - 我不想在父类中创建它们并将它们设置为 None,因为这不会强制开发人员在子类中实现它们。

一些代码来演示当前情况:

class Pet(object):
    name = None

    def make_noise(self):
        raise NotImplementedError("Needs to implement in subclass")

    def print_my_name(self):
        print(self.name)

class Dog(Pet):
    # how to force declairing "name" attribute for subclasses?

    def make_noise(self):
        print("Whof Whof")

在此示例中,开发人员 1 创建了 Pet 类,并希望其他开发人员实现具有“name”属性的子类。 Developer2 实现了一个子类,但不知道他需要实现“name”属性。

是否可以在Python中创建这样的限制?

python inheritance interface
3个回答
1
投票

您可以尝试使用ABCMeta元类或ABC。 之后,您可以使用 @property@abstractmethod。 例如:

from abc import ABC

class Pet(ABC):
    @property
    @abstractmethod
    def name(self):
        pass

    @abstractmethod
    def make_noise(self):
        raise NotImplementedError("Needs to implement in subclass")

    def print_my_name(self):
        print(self.name)

使用此功能,您还可以使用

@name.setter
添加设置器。


0
投票

我也有这个问题一段时间了。读完@Sheng Zhuang 的评论后,我认为他的建议是正确的选择。

如果

name
Pet
使用的属性,并且确实必须为所有
Pet
定义,但不同类型的
Pet
之间可能有所不同,那么处理此问题的正确方法是使用参数输入
Pet
__init__
功能。

class Pet(object):
    def __init__(self, pet_type, name):
        self.pet_type = pet_type
        self.name = name

    def make_noise(self):
        raise NotImplementedError("Needs to implement in subclass")

    def print_my_pet_type(self):
        print(self.pet_type)

    def print_my_name(self):
        print(self.name)

class Dog(Pet):
    def __init__(self, name):
        super().__init__(pet_type='dog', name=name)

    def make_noise(self):
        print("Whof Whof")

我添加了

pet_type
name
进行比较。

pet_type
是编写
Dog
的开发人员可以/应该传递给
Pet.__init__

name
仍然暴露给
Dog
类的最终用户,他们可以传入任何他们喜欢的内容。

编辑:我认为语义上的缺点是

pet_type
并不是像
name
那样真正的实例属性。目的是所有
Dog
都将具有相同的
pet_type
,因此如果
Pet
能够以某种方式强制所有子类必须将
SubPet.pet_type =
定义为类属性,那么在语义上会更加一致,但考虑到有没有干净的方法来做到这一点,我认为通过
super()
传递的实例属性是正确的方法。


-1
投票

使用可以根据您的要求使用Python的

Abstract Base Class
/
ABS
Method Overriding
对您来说可行。

© www.soinside.com 2019 - 2024. All rights reserved.