Python是否适用面向对象设计原则?

26

看起来很多OO的讨论都使用Java或C#作为示例(如Head First设计模式)。

这些模式是否同样适用于Python?如果我遵循这些设计模式,是否最终会在Python中编写Java(这显然是非常糟糕的)?


4
“明显地”这样写其实不好,因为需要用A语言的方式书写而不是B语言。无论哪种语言都一样。把Python用Perl的方式写也可能同样糟糕。 - Adriano Varoli Piazza
3
设计模式本身应该是与编程语言无关的 - 有些文本可能会使用特定的语言来讨论具体实现,但设计模式应该处于不同抽象层级。 - Geoglyph
请参见 https://dev59.com/40XRa4cB1Zd3GeqPqUm4。 - S.Lott
10个回答

36

Python最大的区别在于它是鸭子类型,这意味着你不需要像Java那样详细规划类层次结构,并且它支持头等函数。例如,策略模式变得更加简单和明显,因为你可以直接传递一个函数,而不需要创建接口等来模拟高阶函数。更一般地说,Python为许多常见的设计模式提供了语法糖,例如迭代器和前面提到的策略模式。了解这些模式可能很有用(我读过《Head First》并发现它非常有用),但考虑使用Pythonic方式来实现它们,而不仅仅是像在Java中做事情一样。


13

Python有自己的设计习惯。一些标准模式适用,而其他模式则不适用。例如,策略或工厂这样的模式具有内置支持,使它们变得透明。

例如,使用一等类型,任何东西都可以是工厂。不需要工厂类型,您可以直接使用类来构造所需的任何对象。

基本上,Python有自己的设计习惯,这些习惯在很大程度上与其动态性和令人难以置信的内省能力有关。

示例:

x = list
my_list = x(range(0,5)) #creates a new list by invoking list's constructor

通过将类类型分配给可调用对象,您可以从代码中基本上删除任何“工厂”类型。您只剩下产生应符合某些给定约定的对象的可调用对象。

此外,在Python中有些设计模式在其他静态类型语言中效率不高。元类和函数装饰器就是很好的例子。


4
这取决于模式。在Python中,有些事情很难实现:单例就是一个例子。你可以用另一种模式来替换它,比如,在单例的情况下,使用Borg模式。
在Python中使用设计模式并不疯狂——例如,迭代器模式已经集成到语法中。然而,许多东西并不像面向对象或模式密集型的内容那样完成。Python被设计为在最适合任务的时候以过程化或函数式方式运行,也可以是面向对象的。
总的来说,我只想说,请根据自己的判断力来使用它们。如果看起来使用Alpha-Gamma设计模式会过度复杂,那么它可能确实如此。如果看起来这个模式完全符合你的需求,那么它可能就是这样。

单例模式的价值本来就存在争议。关于主题:设计模式只不过是用胶带纸把语言的缺陷修补起来罢了。 - user21037

4

设计模式仅仅是一种弥补语言缺陷的万能胶。


我曾试图解释我的观点,但它太长了,无法合理地放在评论中,因此我提供了这个链接:http://c2.com/cgi/wiki?AreDesignPatternsMissingLanguageFeatures - user21037
"设计模式列表和一种(在很大程度上)替代它们的语言特性"。两列都是设计模式列表。左边是四人帮模式,右边是其他模式,这些模式恰好不在《设计模式》一书中。仍然不认为模式就是胶布。" - S.Lott
S.Lott:我承认我的评论可能有些过于概括,也许你永远无法构建一个不需要设计模式的语言,但我确实认为它们是用来实现“缺失”语言特性的代码技巧。例如,根据Peter Norvig的说法,Lisp消除了... - user21037
我在Python中使用的语言特性(例如,最常用的可能是迭代器)要么消除了它们的需求,要么使它们透明化,因此我几乎不需要像在Java或C++中那样频繁地使用它们。我想你可以说它们仍然被使用,只是已经内置到语言中了。 - user21037
1
虽然丹很能说会道,但他的观点确实有道理。更具体地说,“设计模式”运动经常解决特别棘手的Java“缺陷”。当事物被内置和设计时,“习惯用法”可能是一个更好的名称。 - Gregg Lind
显示剩余4条评论

4

简短回答:是的,Python 是一种面向对象的语言。

稍微详细点的回答:是的,你可以使用面向对象的原则进行设计,然后在任何语言中实现(甚至是汇编语言)。

使用面向对象的语言的好处在于它包含许多常见的面向对象概念的支持,因此您不必冒着通过约定模拟它们而产生不必要的错误风险。当然,总会有更具适用性或较小适用性的特定于语言的细节;您问的是“设计原则”,这应该表达在那个细节层面之上。

长、啰嗦、无聊的回答:(编程语言的发展并不是一个简单的线性进展,但我为了简化问题并忽略这个事实来做出一个跨越大约 40 年的编程经验观察。)

语言功能与设计原则和模式之间始终存在作用。在每个阶段,注意力集中的从业者都会注意到:

  • “这是我们在当前语言中一直手动解决的问题。”

  • “这是我们在当前语言中一直写入的错误。”

  • “这是我们在最好的程序中一直观察到的一些良好实践。”

因此,下一代语言往往会提供对观察到的良好行为的支持,往往会纳入概念,以便不必通过约定/协议(或者被同样破坏)来完成它们,并强制执行可以避免易于避免的错误的实践。

无论我们的工具有多么复杂、专业化或通用,总会有程序员“只是转动曲柄”,还有其他人不断观察“最优秀的”(在观察者看来)如何使用这些工具。然后他们描述和推广那些实践。正确定义的(无论称之为“风格”,“指南”,“模式”,“原则”等),这些实践最终形成了我们始终试图达到的“下一个级别”,无论我们当前站在哪里。


3

进一步思考后,一些模式(比如Borg模式)可能更适用于Python(尽管其他模式和语言也有类似的情况)。

迭代器模式在Python中也被使用,只是形式稍有不同。

Duncan Booth撰写了一篇关于Python模式的文章


1

我认为这些适用于在 Python 中进行面向对象编程时。请记住,Python 可以做的远不止面向对象编程,您应该在选择适用于工作的范式时使用常识。如果您决定将程序表示为一组对象,则可以使用设计模式,但是如果需要的话,不要害怕尝试完全不同的方法。


1

是的,当然适用。但正如上面所提到的,许多模式已经内置于语言中,或者被语言的高级特性所取代而变得无关紧要。


0

是的,你可以在Python中使用很多设计模式。设计模式只是一个可重复实现高级任务的方法。Python和设计模式之所以与其他语言不同,是因为Python包含了大部分基本模式。这意味着在Python中出现的模式很可能是更高级别的设计模式,而不是通常需要模式的琐碎任务。


0

使用Java或C#可能是由于这些语言的主流流行度。

但是,无论您使用哪种语言,设计原则和/或设计模式都适用。在Python中实现相同的设计模式显然与在Java或C#中不同。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接