在Python中解释继承

时间:2014-01-11 14:02:45

标签: python

我正在浏览一些Python代码并找到了这段代码

class A(object):
    ...
    def add_commands(self, cmd):
        self.commands.append(cmd)
    ...

class B(A):
    ...
    def __init__(self):
        self.commands = []
    ...

现在,由于继承,B将可以访问方法'add_commands'。让我感到惊讶的是,即使A类不知道列表'命令',这个程序编译得很好,忘记了对象B上的方法执行,结果也很好。它出错的唯一时间是我们创建类A的对象并调用方法'add_commands'。我知道它的'self'关键字可以帮助我们。在C ++这样的编程语言中不会出现这种情况,因为编译本身就失败了。

这让我想到了一个问题 - 如何在Python等编程语言中实现继承?考虑到上面的例子,是用Python设计类的正确方法吗?

2 个答案:

答案 0 :(得分:2)

我认为如何在Python中继承继承的问题太广泛,无法在一篇文章中回答(我开始查看官方文档)。我想补充的内容如下:

不要将完全相同的继承设计原则应用于Python上的编译语言(如C ++或Java)。 Python的最大优势之一是它的灵活性(如果使用得当,这是一个危险但非常强大的工具)。

Python没有报告您在上面发布的代码中的任何错误,因为从Python的角度来看,它没有错误(显然是因为Python被解释而不是编译)。 pythonic 做事的方式通常不是其他语言的推荐(甚至可能)。

您可能会发现自己处于某种情况(如评论中已经指出的那样),您希望在其中定义要从其父方法访问的子项中的属性。我试图想出一个例子,希望它会有所帮助。

想象一下,您有两个代表两个不同资源(数据库,文件等)FirstResourceSecondResource的类。每个资源都有自己的方法,但它们都具有结构相似性,导致某些方法具有相同的实现,并且这些操作处理某些属性resource_attrresource_attr的初始化逻辑对于每个资源都是不同的。

也许这可能是解决这种情况的实施选项:

class BaseResource(object):

    def common_operation_a(self):

        # Use self.resource_attr to do Operation A

    def common_operation_b(self):

        # Use self.resource_attr to do Operation B

class FirstResource(BaseResource):

    def __init__(self):

        self.resource_attr = initialize_attr_for_first_resource()

    # ... FirstResource specific operations

class SecondResource(BaseResource):

    def __init__(self):

        self.resource_attr = initialize_attr_for_second_resource()

    # ... SecondResource specific methods

然后您可以按如下方式使用此实现:

# Create resources objects

first_resource_instance = FirstResource()
second_resource_instance = SecondResource()

# The resources share the implementation of Operation A

first_resource_instance.common_operation_a()
second_resource_instance.common_operation_a()

# The following implementations are resource-specific

first_resource_instance.some_operation_c()
second_resource_instance.some_operation_d()

答案 1 :(得分:1)

Python中的继承使用与面向对象继承相同的范例。作为一种解释性语言,你可以使用很多东西,但这并不意味着你的类不应该像编写Java和C ++这样的编译语言一样谨慎设计。