Python设计指南: 我是一个经验丰富的开发人员,多年来一直从事德尔福、C、C++等多项繁重的工作。我一直非常严格地遵守结构化编程、面向对象编程、松散耦合模块化设计等的指导原则——由于我使用的所有语言都有内置的方式来实施这些概念——访问控制、静态类型、接口和抽象类支持等——我依靠这些来构造代码

Python设计指南: 我是一个经验丰富的开发人员,多年来一直从事德尔福、C、C++等多项繁重的工作。我一直非常严格地遵守结构化编程、面向对象编程、松散耦合模块化设计等的指导原则——由于我使用的所有语言都有内置的方式来实施这些概念——访问控制、静态类型、接口和抽象类支持等——我依靠这些来构造代码,python,oop,interface,encapsulation,Python,Oop,Interface,Encapsulation,现在,我已经用Python涂鸦几个月了。它的许多精彩特性给我留下了深刻的印象,但我非常怀念使代码易于模块化和组织化的内置约束。而且,不幸的是,我看到了很多用Python编写的“意大利面代码”,甚至是来自非常值得尊敬的来源。我不会挑出任何人,但我有几本由职业大联盟蟒蛇主义者写的书,书中充满了让我不寒而栗的设计(更确切地说是“反设计”)。在我看来,因为Python非常容易使用,所以它也很容易被滥用 当我用Python编写代码时,我确实试着约束自己,但我发现实现它需要很多额外的工作,而且通常我必须根据

现在,我已经用Python涂鸦几个月了。它的许多精彩特性给我留下了深刻的印象,但我非常怀念使代码易于模块化和组织化的内置约束。而且,不幸的是,我看到了很多用Python编写的“意大利面代码”,甚至是来自非常值得尊敬的来源。我不会挑出任何人,但我有几本由职业大联盟蟒蛇主义者写的书,书中充满了让我不寒而栗的设计(更确切地说是“反设计”)。在我看来,因为Python非常容易使用,所以它也很容易被滥用

当我用Python编写代码时,我确实试着约束自己,但我发现实现它需要很多额外的工作,而且通常我必须根据自己对设计的记忆来设置和遵守约束,而根本不需要语言的帮助。而且,由于没有“编译时”检查,这是加倍困难的——通常在实际运行该段代码之前,您不会发现设计缺陷

因此,我正在寻找非常具体的信息:一些示例,或者更好的是一本关于结构良好的Python设计和设计技术的书——如何最好地实现封装、间接寻址、非常松散耦合的设计等

来自一位著名python书籍作者的糟糕设计-(带有模糊)


关于设计模式的支持

有一种观点认为,设计模式是编程语言中差距的粗略度量。这将是一个有趣的阅读,并与您的建议相对应,即设计模式是语言支持的约束


我发现实现和编译只基于我自己的设计记忆而遵守约束的代码需要大量额外的工作,而在编译之前编写代码时没有语言的帮助。一些IDE提供了帮助,但语言本身却没有给我任何帮助

而且,由于“编译时”检查似乎从未帮助我发现普通的逻辑错误,这就更加困难了——通常在实际运行该段代码之前,您不会发现设计缺陷

Python设计和设计技术。。。 如何最好地实现封装


通过封装。在java和C++这样的语言中,“封装”已经发展成“在整个地方使用私有的东西”。在Python中,这是不被支持的。p> 我们都是成年人。

您仍然像在其他语言中一样进行封装。但是,没有单词
private

Python为
\uuu getattribute\uuu
提供属性、装饰器和重写,以实现各种封装技术

间接的

通过引用其他对象。我不清楚您在这里遇到了哪些具体问题,但可能您向函数传递了一些错误的类型参数。避免这种情况的方法是阅读您自己编写的文档字符串

非常松散耦合的设计等

通过依赖注入。再一次。Python在松耦合方面与其他语言一样工作

您应该大量调查并使用docstring

您可能希望使用从docstring生成漂亮的文档


还可以使用Python内置的代码>帮助()(代码)>函数来读取编写代码时所写的文档字符串。

查看你认为“反设计”的例子会很有帮助。一般来说,我发现访问控制是愚蠢的,接口/抽象类完全不必要。当代码与概念/操作,而不是具体的接口编程时,代码更通用,而C++也是如此,其中模板是编译时的鸭式输入的一种形式。也就是说,接口和abc都可以在Python中实现-参见例如
zope.interface
或stdlib
abc
模块。也许广泛使用单元测试可以帮助您——它们在Python中比在静态类型语言中更重要。Python是灵活的和自适应的。您不会发现任何类型的约束你已经习惯了从其他语言中学习。这是它的优势之一。我认为大多数python用户认为设计模式是从代码中产生的,而不是注入到代码中的。“我们在这里都是成年人”-听起来不错。不幸的是,许多“成年人”的行为似乎像孩子一样…@Mikey:这是什么意思?他们阅读文档并违反规则?他们有源代码,你知道,并且也可以修改这些源代码?你在说什么?“到处使用私人内容。”不。这意味着通过接口公开代码的使用者(甚至你自己)需要并“隐藏”它们不需要的东西。为什么?它使代码更健壮,易于修改和适应。一个好的接口永远不需要更改,即使实现细节可以/将要更改。封装意味着您可以本地化更改并对实现进行大的修改,而不破坏其余代码。当您有一个脚本中有3个文件,只有你自己控制。但在团队维护的大型复杂应用程序中,这是一个巨大的问题。有没有尝试过修改5年前的speghetti代码,而所有原始开发人员都消失了?有没有交付过一个大型应用程序,然后了解到客户想要迁移到新的数据库系统或操作系统?@Mikey:“这意味着通过接口公开代码的消费者(甚至你自己)需要什么,并“隐藏”他们不需要的东西。”
def populateList(self, selecteddisk=None):
selected = None ***#Bundling - coupling:*** 
self.listWidget.clear()
for disk in self.disks.inOrder():
item = QListWidgetItem(QString("%1 of %2/%3 (%L4)") \
.arg(disk.name).arg(disk.owner).arg(disk.country) \
.arg(disk.teu))
self.listWidget.addItem(item)
***#Bundling - coupling:*** 
if selecteddisk is not None and selecteddisk == id(disk):
    selected = item
    if selected is not None:
    selected.setSelected(True)
    self.listWidget.setCurrentItem(selected)