Python中的参数化继承?

Python中的参数化继承?,python,inheritance,python-3.6,Python,Inheritance,Python 3.6,我很好奇是否有更好的方法来实现这样的目标? 我的意图是避免不必要的陈词滥调。所提供的示例显然足够简单,可以让其他人理解我的想法 def create_parametrized_class(animal): class SomeClass: def __init__(self, name): self.name = name def __str__(self): return "{}: {}".format(

我很好奇是否有更好的方法来实现这样的目标? 我的意图是避免不必要的陈词滥调。所提供的示例显然足够简单,可以让其他人理解我的想法

def create_parametrized_class(animal):
    class SomeClass:
        def __init__(self, name):
            self.name = name

        def __str__(self):
            return "{}: {}".format(animal, self.name)

    return SomeClass

class Cat(create_parametrized_class("Cat")):
    pass

class Dog(create_parametrized_class("Dog")):
    pass

cat = Cat("Micka")
dog = Dog("Rex")
assert str(cat) == "Cat: Micka", "Cats..."
assert str(dog) == "Dog: Rex", "Dogs..."

我假设
type(self)。\uuuu name\uuuu
在这里不够(对于两个示例类,该值都等于传入的参数值)

要在类定义时设置每个类的值,从Python 3.6开始,您可以使用:


\uuuu init\u subclass\uuuu
是为所有新的子类调用的,您在
class subclass(…)
行中指定的任何参数都会传递到该方法中,让您对特定的子类进行参数化。

我认为您最好使用简单的继承和一个类变量:

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

    def __str__(self):
        return '{}: {}'.format(type(self).name, self.name)

class Cat(Animal):
    name = 'Cat'

class Dog(Animal):
    name = 'Dog'
在我看来,这看起来更清晰(特别是如果你有更多的变量而不仅仅是一个),并且使用了更少的“高级”功能(即,阅读你的代码的人不必搜索
\uu init\u子类的工作方式)

它也适用于Python 2和Python 3:

>>> cat = Cat('Micka')
>>> print(cat)
'Cat: Micka'

如果要使用,甚至可以将其默认为类的名称,并可使用简单的类变量重写。但这会阻止您对类和实例变量使用相同的名称,因此您必须使用类似
animal\u name

class Animal(object):

    @classproperty
    def animal_name(cls):
        return cls.__name__

    def __init__(self, name):
        self.name = name

    def __str__(self):
        return '{}: {}'.format(self.animal_name, self.name)


class Cat(Animal):
    pass

class Dog(Animal):
    animal_name = 'Doggo'
用法示例:

>>> dog = Dog('Mike')
>>> cat = Cat('Bob')
>>> str(dog)
'Doggo: Mike'
>>> str(cat)
'Cat: Bob'

这是什么Python版本?看起来像是3.6+,因为Martijn Pieters的答案就足够了,但是你应该为其他可能遇到同样问题的人贴上标签<代码>\uuuu init\u子类\uuuuu
在3.6之前不起作用。好的,我添加了Python3.6标记。我不知道init_子类,所以我不确定它是什么Python版本。你应该总是用你正在使用的版本来标记它,这样人们就可以根据它提供答案。您可以使用
python--version
python3--version
查看版本,我知道我使用的是什么版本:)问题是我不希望解决方案是3.6特定的。但是因为我用的是3.6,所以我不介意。不过还是要谢谢你的提示。@MarkusMeskanen:现在在答案中明确指出了。而且,这对答案并不重要,但既然我们已经在3.6上了,为什么不
返回f'{self.\u animal_name}:{self.name}
;)@马库斯梅斯卡宁:因为我专注于问题的主要方面;我试图只在语法改变对代码风格有实质性改进的情况下引入语法改变。当然,我也更喜欢新的
f'…'
语法,但我觉得它会分散我对答案重点的注意力。:-)很公平,一次一个新功能。(虽然我个人认为f字符串是个例外,但它们太吸引人了)。@MarkusMeskanen:它们让Python执行起来更快,并且把槽和表达式放在一个地方(让大脑更容易看到哪里去了)。是的,看起来不错。非常感谢。我更愿意保留Python 3.6解决方案,因为我最初的目的是学习一些新东西。:)
>>> dog = Dog('Mike')
>>> cat = Cat('Bob')
>>> str(dog)
'Doggo: Mike'
>>> str(cat)
'Cat: Bob'