我正在努力寻找一种“pythonic”方法来组织以下类:
我有一个基类,其属性在其构造函数中初始化,例如:
class Animal(object):
def __init__(self, class_, species, is_domesticated):
self.class_ = class_
self.species = species
self.is_domesticated = is_domesticated
然后,当我子类化时,我想“硬编码”这些属性中的一个或多个,如下所示:
class Mammal(Animal):
def __init__(self, species, is_domesticated):
Animal.__init__(self, 'Mammal', species, is_domesticated)
Mammal 是这样实例化的:
monkey = Mammal('Primate', false)
问题是,我想使用 *args 以便在更改基类定义时单独保留任何派生类。因此,哺乳动物的定义变为:
class Mammal(Animal):
def __init__(self, *args):
Animal.__init(self, *(args + (class_='Mammal',)))
这(不用说)看起来很可怕。一些提示将不胜感激 =)
最佳答案
如果您在基类中只有一组固定的参数,则不必担心可变参数。只需按照您在第一个示例中所做的操作就可以了。如果您希望能够向基类随机添加参数,但将它们添加为位置参数并且没有默认值,那是没有希望的;您不能随意更改基类并期望所有派生类继续工作。
但是,有一种相当常见的中间情况,您可能拥有大量属性,这些属性的各种组合可能会传递给层次结构中的任何类。您可能想向基类添加新参数,但它们将具有默认值,因此派生类不需要明确了解它们;他们只会优雅地降级为基类默认值。在这种情况下,通常最好使用 **kwargs
而不是 *args
。
class Animal(object):
def __init__(self, **kwargs):
self.class_ = kwargs['class_']
self.species = kwargs['species']
# etc.
class Mammal(Animal):
def __init__(self, **kwargs):
Animal.__init__(self, class_="Mammal", **kwargs)
这需要通过关键字传递参数:
>>> Animal(class_='Fish', species='barracuda', is_domesticated=False)
4: <__main__.Animal object at 0x0177ABF0>
>>> Mammal(species="monkey", is_domesticated=False)
5: <__main__.Mammal object at 0x0177AFB0>
. . .但是如果它们很多的话会更好,因为如果你有 10 个不同的东西按位置传递,没有人会记得传递它们的顺序。这也意味着您可以轻松添加新参数;没有人需要知道在列表中的什么地方放置新的,他们可以通过关键字将它们添加到任何地方。
在 Python 2 中,您必须像我上面那样手动提取 kwargs。在 Python 3 中你可以使用 keyword-only arguments使这更容易。
关于python - 是否有针对所需属性 (OOP) 的 "pythonic"方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12377128/