【发布时间】:2018-04-19 23:32:10
【问题描述】:
我正在使用 python 3.6。 我的目标是创建一个能够以某种方式通过多态访问的基类——子类变量之一。 我知道这听起来有点“不是 oop”,所以如果我描述的内容不能用 python 完成 - 我想知道这种情况下的最佳做法是什么。
按照维基百科的例子:
class Animal:
def __init__(self, name): # Constructor of the class
self.name = name
def talk(self): # Abstract method, defined by convention only
raise NotImplementedError("Subclass must implement abstract method")
class Cat(Animal):
def talk(self):
return 'Meow!'
class Dog(Animal):
def talk(self):
return 'Woof! Woof!'
animals = [Cat('Missy'),
Cat('Mr. Mistoffelees'),
Dog('Lassie')]
for animal in animals:
print animal.name + ': ' + animal.talk()
打印以下内容:
Missy: Meow!
Mr. Mistoffelees: Meow!
Lassie: Woof! Woof!
我想获得完全相同的输出 - 使用
变量重载(这是一件事吗?)而不是方法重载。
原因是在我正在处理的程序中 - dog、cat 和所有其他类型的 animal 将以完全相同的方式 talk - 仅受数据成员的影响,例如:
class Animal:
def __init__(self, name): # Constructor of the class
self.name = name
self.vocabulary = [] # so called abstract data member
def talk(self): # Non Abstract method, all animals would talk
for word in self.vocabulary: print (word)
class Cat(Animal):
vocabulary = ["Meow", "Muuuew", "Maow"]
class Dog(Animal):
vocabulary = ["Woof", "Waf", "Haw"]
animals = [Cat('Missy'),
Cat('Mr. Mistoffelees'),
Dog('Lassie')]
for animal in animals:
print animal.name + ': ' + animal.talk()
打印以下内容:
Missy: Meow Muuuew Maow
Mr. Mistoffelees: Meow Muuuew Maow
Lassie: Woof Waf Haw
显然,这不起作用,因为词汇表是空的,就像在基类中一样。
我尝试使用super 寻找解决方案,例如:
class Cat(Animal):
vocabulary = ["Meow", "Muuuew", "Maow"]
def talk(self):
super(Animal,Cat).talk()
但结果会是AttributeError: 'super' object has no attribute 'talk'
我用super错了吗?
【问题讨论】:
-
在您的示例中,
vocabulary是Animal的实例属性,但是Dog和Cat的类属性。它实际上应该住在哪里? -
感谢您的评论,词汇应该是类属性,而不是实例变量。
-
您的编辑过多地改变了问题的性质;我已经恢复了。如果您想要一个对类而不是实例进行操作的方法,请查找
classmethod。
标签: python python-3.x oop inheritance polymorphism