对所需属性(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