【问题标题】:__init__ and the setting of class variables__init__ 和类变量的设置
【发布时间】:2012-12-03 13:53:49
【问题描述】:

我在理解类中的继承时遇到了一些麻烦,想知道为什么这段 python 代码不起作用,谁能告诉我这里出了什么问题?

## Animal is-a object 
class Animal(object):
    def __init__(self, name, sound):
        self.implimented = False
        self.name = name
        self.sound = sound

    def speak(self):
        if self.implimented == True:
            print "Sound: ", self.sound

    def animal_name(self):
        if self.implimented == True:
            print "Name: ", self.name



## Dog is-a Animal
class Dog(Animal):

    def __init__(self):
        self.implimented = True
        name = "Dog"
        sound = "Woof"

mark = Dog(Animal)

mark.animal_name()
mark.speak()

这是通过终端的输出

Traceback (most recent call last):
  File "/private/var/folders/nd/4r8kqczj19j1yk8n59f1pmp80000gn/T/Cleanup At Startup/ex41-376235301.968.py", line 26, in <module>
    mark = Dog(Animal)
TypeError: __init__() takes exactly 1 argument (2 given)
logout

我试图让动物检查是否实现了动物,如果是,则获取从动物继承的类以设置动物随后能够操作的变量。

【问题讨论】:

  • 请注意,您的if 声明在这里有点奇怪。 if self.implimented == True: 可以简化为 if self.implimented:
  • 但是之前不是在init中设置为false吗?

标签: python variables inheritance


【解决方案1】:

katrielalex 很好地回答了您的问题,但我还想指出,您的课程编码有些糟糕——如果不是错误的话。您使用类的方式似乎很少有误解。

首先,我建议阅读 Python 文档以了解基本概念:http://docs.python.org/2/tutorial/classes.html

要创建一个类,您只需这样做

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

现在您可以通过调用a1 = Animal("Leo The Lion", "Rawr") 左右来创建名称对象。

要继承一个类,你可以:

# Define superclass (Animal) already in the class definition
class Dog(Animal):

    # Subclasses can take additional parameters, such as age
    def __init__(self, age):

        # Use super class' (Animal's) __init__ method to initialize name and sound
        # You don't define them separately in the Dog section
        super(Dog, self).__init__("Dog", "Woof")

        # Normally define attributes that don't belong to super class
        self.age = age

现在您可以通过说d1 = Dog(18) 创建一个简单的Dog 对象,并且您不需要使用d1 = Dog(Animal),您已经在第一行class Dog(Animal): 告诉类它的超类是Animal

【讨论】:

  • @lerugray 我一直不确定 LPTHW 是否是为了模仿。我绝对不认为这是学习 Python 的一种方式。我推荐How to Think Like a Computer Scientist
  • 如果您希望每只动物都有一个年龄,您可以在父类Animal 中同时定义ageprintAge。如果你想让一些动物有一个年龄,你可以从Animal继承AgedAnimal,这将实现ageprintAge,然后从AgedAnimal继承Dog。如果只有Dog 有年龄,则将ageprintAge 编码为Dog,并保持Animal 不变。
  • @lerugray 你会在Animal.__init__() - 方法中初始化age,是的。如果有两个或多个具有公共属性的类(例如age),则将公共属性编码到它们的基类中。
  • @Lattyware 多重继承可能是为了这个确切的目的而设计的,但不,它没有意义。首先,我是一个 C++ 程序员,而不是 Java 程序员,每个人都表现得好像他们对另一个人有所了解,或者每个人都是 Java 程序员,这有什么问题?其次,大多数编程语言不支持多重继承是有原因的:这是一种混乱、糟糕的编码方式,并且违反了好代码中的所有可能规则。正如我所提到的,如果您要创建一个真正的大型项目,那么无论使用哪种语言,都不能使用多重继承。
  • @Mahi 我用 Java 作为不支持 MI 的非常严格的语言的一个例子——我并不是说你是 Java 程序员。如果您能给出 MI 是一件坏事的一些实际原因,那就太好了 - 我很高兴阅读链接。我同意它可以用来产生不良影响,但我不认为它总体上是一件坏事。
【解决方案2】:
  1. 创建一个类的实例

    mark = Dog()
    

    不是mark = Dog(Animal)

  2. 不要这样做implimented 的东西。如果您想要一个无法实例化的类(即您必须先进行子类化),请执行

    import abc
    class Animal(object):
        __metaclass__ = abc.ABCMeta
    
        def speak(self):
            ...
    

【讨论】:

  • 为什么不做实现的东西呢?有什么更好的方法来检查代码以查看动物(类)是否存在?或者例如,如果其中一只动物是不会说话的考拉。
  • @lerugray 你不能两全其美:如果你将动物定义为会说话的东西,那么不会说话的考拉就不是动物。
  • 你当然可以为那些不会说话的动物设置self.sound = None,然后在你的speak方法中检查声音是否不是None。
【解决方案3】:

由于给定示例中的年龄不是父(或)类的一部分,因此您必须实现该函数(在一个类中称为方法 ) 在继承的类(也称为派生类)中。

class Dog(Animal):

    # Subclasses can take additional parameters, such as age
    def __init__(self, age):
        ... # Implementation can be found in reaction before this one

    def give_age( self ):
        print self.age

【讨论】:

  • 这到底给我的答案增加了什么?您不必必须实现一个您不需要的方法。这个答案实际上是不正确的,它可能只会分散新手的注意力。
  • @Mahi:在我给出答案的时候,我假设 OP 想要在派生类中实现年龄,因为那是你的示例的一部分,我只用作基础。我假设他想要一种方法来从那个问题中获取年龄。我只是想帮忙。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-03-26
  • 1970-01-01
  • 1970-01-01
  • 2012-03-06
  • 2012-04-11
  • 2010-12-31
  • 2011-07-23
相关资源
最近更新 更多