我正在浏览一些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设计类的正确方法吗?
答案 0 :(得分:2)
我认为如何在Python中继承继承的问题太广泛,无法在一篇文章中回答(我开始查看官方文档)。我想补充的内容如下:
不要将完全相同的继承设计原则应用于Python上的编译语言(如C ++或Java)。 Python的最大优势之一是它的灵活性(如果使用得当,这是一个危险但非常强大的工具)。
Python没有报告您在上面发布的代码中的任何错误,因为从Python的角度来看,它没有错误(显然是因为Python被解释而不是编译)。 pythonic 做事的方式通常不是其他语言的推荐(甚至可能)。
您可能会发现自己处于某种情况(如评论中已经指出的那样),您希望在其中定义要从其父方法访问的子项中的属性。我试图想出一个例子,希望它会有所帮助。
想象一下,您有两个代表两个不同资源(数据库,文件等)FirstResource
和SecondResource
的类。每个资源都有自己的方法,但它们都具有结构相似性,导致某些方法具有相同的实现,并且这些操作处理某些属性resource_attr
。 resource_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 ++这样的编译语言一样谨慎设计。