编程语言
首页 > 编程语言> > 对所需属性(OOP)有“pythonic”方法吗?

对所需属性(OOP)有“pythonic”方法吗?

作者:互联网

我正在努力为下面的班级组织找到一个“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)

因此,哺乳动物就像这样实例化:

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,inheritance,iterable-unpacking,args
来源: https://codeday.me/bug/20190529/1181653.html