基类访问超类变量

时间:2018-04-19 23:32:11

标签: python python-3.x oop inheritance polymorphism

我正在使用python 3.6。 我的目标是创建一个能够以某种方式通过多态访问的基类 - 一个子类变量。 我知道这听起来有点'不是oop',所以如果用python无法完成我的描述 - 我想知道这个案例的最佳做法是什么。

按照维基百科的例子:

        int wins = 0;

        if (num1 == a1 || num1 == a2 || num1 == a3)
            wins++;
        if (num2 == a1 || num2 == a2 || num2 == a3)
            wins++;
        if (num3 == a1 || num3 == a2 || num3 == a3)
            wins++;

        if(wins == 3)
            if(num1 == a1 && num2==a2 && num3==a3)
                System.out.println("YOU'RE A MILLIONAIRE!");
            else
                System.out.println("You win 1,000 dollars!");
        else if (wins == 2)
            System.out.println("You win 100 dollars!");
        else if (wins == 1)
            System.out.println("You win 10 dollars!");
        else
            System.out.println("You lose!");

打印以下内容:

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和其他所有catanimal完全相同的方式 - 仅受数据成员的影响,例如:

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'错了吗?

2 个答案:

答案 0 :(得分:0)

Python是动态类型的。没有必要以某种方式声明一个"抽象数据成员"在Animal Animal方法中引用self.vocabulary;实际上,您试图声明一个"抽象数据成员"导致你的问题。

只需删除self.vocabulary = []talk会在尝试访问vocabulary时自动找到子类self.vocabulary

答案 1 :(得分:0)

您的代码中存在一些未解决的问题,但由于python是如此动态,它将通过正常查找找到子类实例属性:

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

    def talk(self):
        for word in self.vocabulary: print (word)

class Cat(Animal):
    def __init__(self, name):
      super().__init__(name)
      self.vocabulary = ["Meow", "Muuuew", "Maow"]

class Dog(Animal):
  def __init__(self, name):
      super().__init__(name)
      self.vocabulary = ["Woof", "Waf", "Haw"]

animals = [Cat('Missy'),
           Cat('Mr. Mistoffelees'),
           Dog('Lassie')]

for animal in animals:
    print(animal.name, end=': ')
    animal.talk()

如果您希望在代码中更明确地强制执行此要求,可以将Animal作为抽象基类并创建名为vocabulary的abstruct属性:

import abc

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

    @property
    @abc.abstractmethod
    def vocabulary(self):
      ...

    def talk(self):
        for word in self.vocabulary: print (word)

class Cat(Animal):
    @property
    def vocabulary(self):
      return ["Meow", "Muuuew", "Maow"]

here is a live link