通过学习Pythonthehardway 了解Class Python 中的继承
Understanding Class Inheritance in Python from learningPythonthehardway
我一直在学习Python,我终于明白了classes和对象之间的继承是什么意思。所以这是我的代码,我想确保我理解正确:
class Animal(object):
def __init__(self, name):
self.name = name
print self.name
def howl(self, name):
print "Eeh %s" % name
class Dog(Animal):
def __init__(self, name):
##has-a __init__ function that takes self and name parameters.
self.name = name
print "%s barks and is happy" % self.name
def sound(self, name):
print "%s barks" % name
rover = Dog("Rover")
rover.sound("Rover")
rover.howl("Rover")
为了更好地理解我的 classes 与 "base class" Animal
的行为方式,我把 print
s 到处都是,我可以看到Dog
能够调用 howl
,一个来自其父 class 的函数,Animal
(对吗?)
我的另一个问题是,当我使用 rover = Dog("Rover")
时,为什么它使用 __init__
函数调用?当 __init__
函数真正做的只是为变量设置一个值 (self.name
) 时,它的目的是什么?因为没有人调用 rover.__init__("Rover")
,而且你不能执行 print(rover = Dog("Rover"))
,为什么 Animal
class 的 __init__
函数没有打印出来?
只是要求澄清相关 class 之间的 class 继承和函数行为。
如果你构造一个class,你将需要初始化函数。
因为你覆盖了__init__
函数,如果你不在Dog中写__init__
函数,它会使用Animal的init函数。如果你想使用Animal的init函数,你可以这样做:
class Dog(Animal):
def sound(self, name):
print "%s barks" % name
您的 post 包含多个问题,我们开始吧!
1 Dog
能够从其父 class、Animal
调用 howl
函数(对吗?)
是的,你是对的。
由于您声明 Dog
class 继承自 Animal
- class Dog(Animal)
- Dog
class 将具有所有属性 - 包括方法 - 在中声明Animal
因此你可以给狗打电话 howl
。
2 我用rover = Dog("Rover")
的时候怎么用了__init__
函数调用?
当使用 ClassName(<parameters>)
创建对象时,在幕后发生的事情是 Python 将调用 class 中定义的 __init__
方法ClassName
。有关详细信息,请参阅 the __init__
documentation,这也说明了为什么没有 __init__
方法的 class 将调用其父项的 __init__
方法。本文档还回答了您的子问题 __init__
函数的目的是什么...?。
总体思路是您(几乎)从不直接调用 __init__
方法。
现在是有趣的部分!
3为什么Animal
class的__init__
函数没有打印出来?
在您的代码示例中,Animal
和 Dog
的 __init__
方法几乎相似,即设置 name
属性并打印一些内容。唯一的区别是他们打印的内容。因此,让我们假设您像这样重写 classes:
class Animal(object):
def __init__(self, name):
self.name = name
print "I am an Animal named %s" % self.name
class Dog(Animal):
def __init__(self, name):
super(Dog, self).__init__(name) # That's the important line
print "I am actually a Dog named %s, I bark too!" % self.name
rover = Dog("Rover")
# Output:
# I am an Animal named Rover
# I am actually a Dog named Rover, I bark too!
正如推荐所解释的那样,导入行是在我们调用 super(Dog, self).__init__(name)
时 - 请参阅 documentation - 它将检索 Dog
的超级 class 然后我们调用__init__
方法来初始化当前对象 self
- 因此设置 name
并在 Animal
class 中调用 print
语句。
通过所有这些,您最终可以正确调用 print
!
请注意,您可以通过多种方式调用超级 class 的 __init__
:
Animal.__init__(self, name)
super(Dog, self).__init__(name)
super(self.__class__, self).__init__(name) # self.__class__ is the class of self or its type.
有关各种语法的更深入比较,请参阅 this question。
我一直在学习Python,我终于明白了classes和对象之间的继承是什么意思。所以这是我的代码,我想确保我理解正确:
class Animal(object):
def __init__(self, name):
self.name = name
print self.name
def howl(self, name):
print "Eeh %s" % name
class Dog(Animal):
def __init__(self, name):
##has-a __init__ function that takes self and name parameters.
self.name = name
print "%s barks and is happy" % self.name
def sound(self, name):
print "%s barks" % name
rover = Dog("Rover")
rover.sound("Rover")
rover.howl("Rover")
为了更好地理解我的 classes 与 "base class" Animal
的行为方式,我把 print
s 到处都是,我可以看到Dog
能够调用 howl
,一个来自其父 class 的函数,Animal
(对吗?)
我的另一个问题是,当我使用 rover = Dog("Rover")
时,为什么它使用 __init__
函数调用?当 __init__
函数真正做的只是为变量设置一个值 (self.name
) 时,它的目的是什么?因为没有人调用 rover.__init__("Rover")
,而且你不能执行 print(rover = Dog("Rover"))
,为什么 Animal
class 的 __init__
函数没有打印出来?
只是要求澄清相关 class 之间的 class 继承和函数行为。
如果你构造一个class,你将需要初始化函数。
因为你覆盖了__init__
函数,如果你不在Dog中写__init__
函数,它会使用Animal的init函数。如果你想使用Animal的init函数,你可以这样做:
class Dog(Animal):
def sound(self, name):
print "%s barks" % name
您的 post 包含多个问题,我们开始吧!
1 Dog
能够从其父 class、Animal
调用 howl
函数(对吗?)
是的,你是对的。
由于您声明 Dog
class 继承自 Animal
- class Dog(Animal)
- Dog
class 将具有所有属性 - 包括方法 - 在中声明Animal
因此你可以给狗打电话 howl
。
2 我用rover = Dog("Rover")
的时候怎么用了__init__
函数调用?
当使用 ClassName(<parameters>)
创建对象时,在幕后发生的事情是 Python 将调用 class 中定义的 __init__
方法ClassName
。有关详细信息,请参阅 the __init__
documentation,这也说明了为什么没有 __init__
方法的 class 将调用其父项的 __init__
方法。本文档还回答了您的子问题 __init__
函数的目的是什么...?。
总体思路是您(几乎)从不直接调用 __init__
方法。
现在是有趣的部分!
3为什么Animal
class的__init__
函数没有打印出来?
在您的代码示例中,Animal
和 Dog
的 __init__
方法几乎相似,即设置 name
属性并打印一些内容。唯一的区别是他们打印的内容。因此,让我们假设您像这样重写 classes:
class Animal(object):
def __init__(self, name):
self.name = name
print "I am an Animal named %s" % self.name
class Dog(Animal):
def __init__(self, name):
super(Dog, self).__init__(name) # That's the important line
print "I am actually a Dog named %s, I bark too!" % self.name
rover = Dog("Rover")
# Output:
# I am an Animal named Rover
# I am actually a Dog named Rover, I bark too!
正如推荐所解释的那样,导入行是在我们调用 super(Dog, self).__init__(name)
时 - 请参阅 documentation - 它将检索 Dog
的超级 class 然后我们调用__init__
方法来初始化当前对象 self
- 因此设置 name
并在 Animal
class 中调用 print
语句。
通过所有这些,您最终可以正确调用 print
!
请注意,您可以通过多种方式调用超级 class 的 __init__
:
Animal.__init__(self, name)
super(Dog, self).__init__(name)
super(self.__class__, self).__init__(name) # self.__class__ is the class of self or its type.
有关各种语法的更深入比较,请参阅 this question。