如今,Python似乎风靡一时,而且并非不值得-因为它确实是一种语言,几乎所有人都喜欢用它来解决新问题。但是,正如一个智者曾经说过的(称他为智者,仅是因为我不知道谁真正说了这个;不知道他是否真的是那个智者),真正了解一门语言不仅会知道它语法,设计等优点,但也有缺点。没有一种语言是完美的,有些只是比其他语言更好。
所以,您认为Python的客观缺点是什么。这里的语言比较(即C#比Python更好,因为... yadda yadda yadda)-更多地客观地(某种程度上)认为哪些语言功能设计不良,是否,您可能缺少哪些语言以及以此类推。如果必须使用另一种语言进行比较,而只是为了说明一个要点,否则很难说明(即,为了易于理解)
#1 楼
我经常使用Python,总体而言,我认为它是一种非常好的语言。但是,没有一种语言是完美的。以下是对我个人而言重要的缺点:速度很慢。我的意思是真的,真的很慢。很多时候这无关紧要,但这绝对意味着您需要那些对性能至关重要的位使用另一种语言。
嵌套函数有点烂,您不能在外部范围内修改变量。编辑:由于支持库,我仍然使用Python 2,这个设计缺陷激怒了我,但显然由于非本地语句,它已在Python 3中修复。等不及要移植我使用的库了,这样的缺陷就可以永久地发送到历史的灰堆中了。
它缺少一些对库/通用代码有用的功能,恕我直言,这很简单到不健康的极端。我能想到的最重要的是用户定义的值类型(我猜它们可以用元类魔术创建,但我从未尝试过)和ref函数参数。
它离金属很远。需要编写线程原语或内核代码之类的东西吗?祝您好运。
虽然我不介意缺乏预先捕获语义错误的能力来作为Python提供的动态性的折衷方案,但我希望有一种方法可以捕获语法错误和愚蠢的东西,例如错误地混淆变量名必须实际运行代码。
文档不如像PHP和Java这样具有强大公司支持的语言。
评论
@Casey,我不同意。索引太糟糕了-尝试查找with语句或列表中的方法。教程中涉及的所有内容基本上都是不可搜索的。我对Microsoft的C ++文档更加满意。
– Mark Ransom
2010-10-29 6:14
大约5-只需使用pyflakes。它被编写为恰好捕获那些错误。
–亚历山大·索洛维约夫(Alexander Solovyov)
2011年7月12日在9:13
关于速度:随着PyPy的兴起,许多Python用户现在将能够通过使用带有内置JIT编译器的解释器来处理速度问题(目前,Python 3用户和cpyext无法处理的C扩展模块用户没有此选项)。
– ncoghlan
2011年7月13日在3:07
我鄙视Python文档。当然,它们比大多数人还漂亮,但是很多时候很多有用的信息都集中在一页中,例如字符串和列表中的方法,而且所有序列类型也都集中在一起。当我搜索这些信息时,我只是落在一个巨大的书本上,而不得不向下搜索页面以查找所需内容。我还发现这些页面上的索引很难阅读,有时很难说出我想要哪一部分。
–卡森·迈尔斯(Carson Myers)
11年7月23日在1:53
与金属的距离如何成为争论? Python是否曾经声称自己是系统语言?
–马克·坎拉斯(Mark Canlas)
2012年9月9日下午0:01
#2 楼
我讨厌Python无法区分变量的声明和用法。您无需进行静态输入即可实现这一目标。最好有一种说法:“这是我故意声明的变量,我打算引入一个新名称,这不是错字”。此外,我通常使用Python变量采用一次写入的样式,也就是说,我将变量视为不可变的,并且在首次分配变量后不要对其进行修改。由于有了列表理解等功能,这实际上非常容易,并且使代码流更易于遵循。 Python并没有阻止我覆盖或重用变量的形式。如果我写入未由任何一个声明的变量,Python应该引发错误。此外,
var
将变量声明为只读,而let
变量则为“普通”变量。请考虑以下示例:类型仍然是隐式的(但是let
变量对于所有意图和目的都是静态类型的,因为它们无法反弹到新值,而var
变量仍可以动态类型)。自动为let
,即它们应该是只读的。除了以下习惯用法外,一般没有充分的理由修改参数: /> x = 42 # Error: Variable `x` undeclared
var x = 1 # OK: Declares `x` and assigns a value.
x = 42 # OK: `x` is declared and mutable.
var x = 2 # Error: Redeclaration of existing variable `x`
let y # Error: Declaration of read-only variable `y` without value
let y = 5 # OK: Declares `y` as read-only and assigns a value.
y = 23 # Error: Variable `y` is read-only
评论
我非常希望Python有一个“ var”语句。除了您陈述的理由(非常好)之外,这也使阅读代码变得容易得多,因为您可以在页面上扫描以发现所有变量声明。
–跳楼
2011年7月11日23:19
好像python开发人员忽略了过去的教训。不声明变量,不声明函数是1950年代首先犯的错误。那些难以发现的错字造成的错误在1950年代首次出现就足够了。一次又一次(后来更正)了这种语言错误。声明变量不是很大的负担。它多次救了我的屁股。我不可避免地使用严格;并使用警告;在perl中使用任何大小的脚本。 Python剥夺了开发人员太多的调试辅助工具。
–David Hammen
2011年7月19日0:00
@David,公平起见,如果您尝试访问未分配的变量,它将引发异常。许多缺少声明的语言将返回某种默认值。结果,Python的版本比那些版本的问题要少得多。
–温斯顿·埃韦特(Winston Ewert)
2011年7月23日在23:58
@yi_H该提案并非旨在向后兼容,甚至不是真正的提案。问题是,“ Python的弊端是什么”……好吧,没有var和let(或类似机制)是一个弊端。换句话说:如果我是Python的设计师,我会做这样的事情。也就是说,将来的版本可能会在您加载特殊程序包时包含此功能(类似于__future__)。说,进口严格。不过,这不会发生,因为它需要语法上的破解...
–康拉德·鲁道夫(Konrad Rudolph)
2011年7月24日13:48
+1用于增加更好的“类似于功能”的编程能力。
–伊文·普莱斯
2012年5月2日14:33
#3 楼
我主要抱怨的是线程,由于全局解释器锁定(请参阅“ Inside the Python GIL”(PDF链接)讨论),因此在许多情况下(与Java,C和其他语言相比)它的性能不佳。 >但是,有一个非常易于使用的多进程接口,但是对于相同数量的进程与线程,它将占用更多的内存,如果共享数据很多,则很难。但是,好处是,一旦您的程序可以处理多个进程,它就可以在多台计算机上扩展,这是线程程序无法做到的。我真的不同意对文档的评论,我认为它是出色的,并且比大多数主流语言要好。
此外,您还可以捕获运行pylint的许多运行时错误。
评论
pyint +1。我没有意识到。下次我用Python做一个项目时,我会尝试一下。另外,如果您使用Jython而不是参考CPython实现,则多线程似乎可以正常工作。 OTOH Jython的速度比CPython慢一些,因此这可能会部分破坏其目的。
–dsimcha
10-10-29在0:48
线程支持不好吗?从2.1之前的版本开始,线程库就已经存在。
–rox0r
2010-12-18 7:16
我知道有线程支持,但是与Java或C相比,GIL确实会降低性能。这就是为什么多处理模块优先于线程处理的原因。
–cmcginty
2010-12-20 23:15
如果您可以找到文档,则该文档很好。搜寻Java类比Python容易得多。
–布伦丹·朗(Brendan Long)
2011年7月23日在23:32
@Casey我已经在答案中阐明了措辞,因为支持线程,因此表现出一些奇怪的性能(还添加了参考资料和一些指向文档的链接)
– dbr
2012年9月8日13:05
#4 楼
可以说,缺少静态类型会导致某些类型的运行时错误,这不值得鸭子类型提供的额外灵活性。评论
这是正确的,尽管有PyChecker之类的工具可以检查诸如C / Java之类的语言的编译器会执行的错误。
–奥利弗·韦勒
10-10-28在23:42
动态类型化是有意识的设计决策,而不是缺点。
–missingfaktor
2010年11月11日12:18
就像说Java的弱点是缺乏动态类型一样。
– MAK
2010年11月11日13:36
@ missingfaktor,@ MAK,很明显,鸭式打字是预期的功能。但是大多数设计决策都会带来客观的利弊。增加的代码灵活性是动态键入的好处,而其他潜在的运行时错误类别则是一个缺点。主观部分是该功能是否值得。
–雅各布
2010年11月11日在16:27
静态类型的缺乏使程序员更容易编写有运行时错误的代码。在C#中,int foo = 4; Console.Write(foo.Length);不会编译,因此错误“ Int32没有属性Length”不会意外地进入已发布的软件。在python中,除非您运行可选的辅助工具来查找类似的错误,否则访问对象的不存在成员的代码可能不会被检测到,直到最终导致运行时错误。
–雅各布
2010-12-18在16:29
#5 楼
我认为Python的面向对象的部分感觉有点“笨拙”。您可以说,将“自我”显式传递给每个方法的全部需求是一个症状,即没有明确计划OOP组件。它还显示了Python有时警惕的作用域规则,这些规则在另一个答案中遭到批评。有时,OOP方面会感到很不一致。以Ruby为例:在Ruby中,一切都是对象,您使用熟悉的obj.method
语法调用方法(当然,重载运算符除外);在Python中,一切也都是对象,但是有些方法是作为函数调用的;即,您使__len__
重载以返回长度,但使用len(obj)
而不是其他语言中更常见(更一致)的obj.length
来调用它。我知道这个设计决定背后有一些原因,但我不喜欢它们。另外,Python的OOP模型缺乏任何类型的数据保护,即没有私有,受保护和公共的数据保护成员;您可以在方法前使用
_
和__
模仿它们,但这有点丑陋。同样,Python也不能完全正确地理解OOP的消息传递方面。评论
self参数只是使其他语言保持隐式。这些语言显然具有“自我”参数。
–罗杰·佩特
2010-10-29 6:08
@Roger Pate:是的,但是对“自我”的明确需求有点烦人(我认为这是一个泄漏的抽象)。它也不是有意的设计决定,而是由于Python的“怪异”作用域规则。我找不到快速的文章,但是Guido van Rossum发了一封电子邮件,很好地解释了为什么需要“ self”参数。
– mipadi
2010-10-29 12:54
@Roger Pate:在面向对象的语言中,将目标作为第一个参数传递仍然可以视为实现细节。我的意思不是,不是一个好主意。关键是,在Python中,这不是由于有意识的设计决定,而是要解决范围系统中的疣。
– mipadi
2010-10-29 14:08
@mipadi:更新具有更好的推理(因此,我将删除downvote),但是如果您将len视为重载的运算符,则在Python中更多。希望看到有关Python如何使消息传递错误的示例或推理。
–罗杰·佩特
2010-10-29 14:23
显式的自我是方法只是函数(正如Winston所指出的那样,隐式局部变量声明)这一事实的产物。您可以自由地不喜欢该设计决策,但是以一种在运行时将所有内容都可以作为对象访问的语言来调用OOP是“愚蠢的”。
– ncoghlan
2011年7月13日在3:22
#6 楼
我不喜欢Python的事情:线程化(我知道它已经被提及,但是在每篇文章中都值得一提)。 (
lambda
只能包含一个表达式)。缺少简单但强大的输入读取函数/类(例如C ++中的
cin
或scanf
和Java中的Scanner
)。默认情况下,所有字符串都不是unicode (但在Python 3中已修复)。
评论
关于(2),我认为这被嵌套函数的可能性所抵消。
–康拉德·鲁道夫(Konrad Rudolph)
2010-12-26 12:13
@KonradRudolph我的主要功能是嵌套函数而不是多行lambda,这是读取顺序被交换了。
–CookieOfFortune
2012年9月8日15:36
@wkschwartz:raw_input和'sys.stdin'都是准系统。他们不支持获取格式化的输入(例如,要及时读取的类似“%d:%d:%d”%(小时,分钟,秒))。到目前为止,Python尚没有任何接近scanf(in C)或Scanner(Java)功能的东西。
– MAK
2012年9月9日下午4:47
@limscoder:在Java中,默认情况下所有字符串都是unicode。我认为没有单独的str和unicode类的充分理由。恕我直言,字符串和字节数组不应以相同的抽象表示。字符串类应该用于存储和处理文本-我们并不在乎其内部表示形式。我们不希望在字符串中的特定字节处执行诸如截断/替换/删除/插入之类的操作-我们希望在特定字符处执行此操作。当输入非英语输入时,很容易忘记区别,并使您的代码崩溃。
– MAK
2012年9月9日下午5:07
@limscoder:如果您想查看简单的unicode,请尝试使用Tcl。几年前,我不得不从Tcl切换到Python,男孩惊讶于原始python的unicode支持有多大。它在Tcl中是真正不可见的,而在python中则是一个主要难题。
–布莱恩·奥克利(Bryan Oakley)
2012年9月10日上午11:00
#7 楼
具有可变数据类型的默认参数。def foo(a, L = []):
L.append(a)
print L
>>> foo(1)
[1]
>>> foo(2)
[1, 2]
通常是一些细微错误的结果。我认为最好在需要默认参数时创建一个新的列表对象(而不是创建一个对象用于每个函数调用)会更好。但是当需要在文档中引用某些内容时,通常意味着存在问题。这不是必需的。
def foo(a, L = None):
if L is None:
L = []
...
尤其是在默认情况下。这只是一个奇怪的行为,与您的预期不符,并且在很多情况下都没有用。
评论
我对此有很多抱怨,但是为什么人们坚持要将一个空列表(该函数进行修改)作为默认参数?这真的是个大问题吗?即,这是一个真正的问题吗?
– Martin Vilcans
2011年7月25日在21:22
它违反了最小惊讶原则。人们不会期望函数的参数在调用之间仍然存在。
–aib
2012年9月9日下午0:19
这是因为它是一种脚本语言。您只会一次被此错误困扰,以后再也不会。亲自找出该错误确实可以使您大吃一惊,以提醒您,是的,它仍然是一种脚本语言。这仅仅是因为该语言在隐藏脚本方面(假设您正确使用了它)方面很有用。
–佐兰·帕夫洛维奇(Zoran Pavlovic)
13年1月7日,下午6:32
@ZoranPavlovic出于好奇,为什么这是脚本语言的结果?绑定数据的时间似乎很成问题,因为列表是可变的(这通常是两件事,但是当组合在一起时,结果却很糟糕)。如果您在函数创建时绑定数据,而不是每次调用函数时都创建一个新列表,则使用非脚本语言可能会发生相同的问题。
–jsternberg
2013年1月7日17:19
@aib:我不这么认为-这里的参数,像其他所有Python对象一样-是指向对象的指针。在这种情况下,对象是可变对象,并且在声明函数时绑定变量。该参数确实可以“跨调用生存”,但是幸存的是对可变对象的引用。
–帕特里克·柯林斯(Patrick Collins)
2013年12月30日23:10
#8 楼
Python的某些功能使其灵活地成为一种开发语言,对于那些使用诸如C ++和Java之类的编译和链接过程进行的“整个程序”静态分析所使用的功能,也将其视为主要缺点。局部变量的隐式声明局部变量是使用普通赋值语句声明的。这意味着任何其他作用域中的变量绑定都需要编译器进行显式注释(外部作用域的全局和非本地声明,实例作用域的属性访问符号)。这极大地减少了编程时所需的样板数量,但是这意味着需要第三方静态分析工具(例如pyflakes)来执行由编译器以需要显式变量声明的语言处理的检查。 >
支持“猴子修补”
可以在运行时修改模块,类对象甚至内置命名空间的内容。这是非常强大的功能,允许使用许多非常有用的技术。但是,这种灵活性意味着Python不提供静态类型的OO语言所共有的某些功能。最值得注意的是,实例方法的“ self”参数是显式的,而不是隐式的(因为不必在类内部定义“方法”,因此可以在以后通过修改类来添加它们,这意味着它不是特别实用)隐式传递实例引用),并且根据代码是在类的“内部”还是“外部”(因为该区别仅在执行类定义时才存在),不能轻易实施属性访问控制。 />
远离金属的
许多其他高级语言也是如此,但是Python倾向于抽象掉大多数硬件细节。像C和C ++这样的系统编程语言仍然更适合于处理直接的硬件访问(但是,Python会通过CPython扩展模块,或者更方便地通过
ctypes
库与它们进行愉快的对话)。#9 楼
使用缩进代码块代替{} / begin-end。
每种较新的现代语言都有适当的词法作用域,而Python没有(见下文)。 Perl5文档,很棒。)
束缚夹克(只有一种方法可以做到)。
范围界定的示例;解释器会话的笔录:
>>> x=0
>>> def f():
... x+=3
... print x
...
>>> f()
Traceback (most recent call last):
File "", line 1, in ?
File "", line 2, in f
UnboundLocalError: local variable 'x' referenced before assignment
global
和nonlocal
关键字已被引入,以修补这种设计愚蠢。评论
关于范围,好奇地看一下python.org/dev/peps/pep-3104可能是值得的,以了解当前方法的原因。
–温斯顿·埃韦特(Winston Ewert)
10-10-30在1:13
同意+1。因此,+ 1。
–Jas
2010年11月11日下午13:12
拥有一种方法是一个优势。当您阅读别人的代码时,您将永远不会解密任何一条语句。一旦习惯用法扎根在您的大脑中,您就应该立即识别。
–rox0r
2010-12-18 7:21
完全同意@ rox0r。 “直截了当”可防止各种语法大战。
–keithjgrant
2011年1月13日在22:03
老实说,我很少需要Python中的global或nonlocal关键字。很少有人忘记了这个问题的存在,尽管我每天在工作时都编写Python代码,但不得不反复搜索它几次。对我来说,需要修改全局变量(或更糟糕的是,外部非全局变量)的代码是代码的味道。通常(并非总是)有更好的方法。
–本
2011年7月24日6:26
#10 楼
我发现python的面向对象this.method()
和过程/功能method(this)
语法的组合非常令人不安: )只是转储到全局名称空间中:与列表,字符串,数字,构造函数,元编程相关的方法,全部混合在一个大的按字母顺序排序的列表中。至少,像F#这样的函数语言在模块中正确命名了所有功能:
x = [0, 1, 2, 3, 4]
x.count(1)
len(x)
any(x)
x.reverse()
reversed(x)
x.sort()
sorted(x)
所以它们并没有在一起。此外,这是整个库中遵循的标准,因此至少是一致的。
我理解执行功能vs方法的原因,但是我仍然认为将它们这样混合起来是一个坏主意。如果遵循方法语法,至少对于常见操作,我会更高兴:
该对象具有几个优点:
在单个位置查找数据类型上的“常见”操作:其他库/等。可能还有其他对数据类型可以做的事情,但是“默认”操作全部在对象的方法中。
调用
Module
时无需继续重复Module.method(x)
。以上面的功能列表示例为例,为什么我必须不断重复说List
?应该知道这是一个List
,我不想在其上调用Navigation.map()
函数!使用x.map()
语法可使它保持DRY且仍然清晰。当然,它比全局名称空间中的一切放置方法具有优势。并不是说当前的方法无法完成任务。它非常简洁(
len(lst)
),因为没有命名空间!我了解使用函数(默认行为等)相对于方法的优势,但我仍然不喜欢它。太乱了在大型项目中,混乱是您最大的敌人。
评论
是的...我真的很想念LINQ样式(我确定LINQ不是第一个实现它的人,但是我最熟悉它)列表处理。
–CookieOfFortune
2012年9月8日15:38
不要将len(x)当作一种方法。 “ len”是一个函数。 Python具有函数和方法,我认为这种方法没有错。通常,缺少适当的功能是许多不必要的键入的来源。
–rbanffy
2012年9月8日在16:42
我知道len()是一个函数,它的优点是什么。我还说了为什么我认为这是一个坏主意,为什么我认为全局函数是一个特别不好的主意,以及为什么我认为方法提供了一种方便的方法来组织和确定功能范围=)
–皓一
2012年9月8日在16:49
我认为42个关键字(或43个关键字)不是一个很大的数字。这还包括def,class和其他非功能调用之类的东西。将其与其他大多数流行语言中的100多种语言进行比较。此外,请考虑import的这一行:命名空间是一个很棒的主意-让我们做更多的事情!我认为您可能会误解Python名称空间;)
–Wayne Werner
2012年9月9日下午4:12
#11 楼
缺乏同质性。Python必须等待3.x添加“ with”关键字。在任何谐音语言中,它都可以被轻松地添加到库中。
我在答案中看到的大多数其他问题属于以下三种类型之一:
1)事物可以通过工具(例如pyflakes)修复的
2)实现细节(GIL,性能)
3)可以通过编码标准修复的事物(即人们不希望的功能) >
#2并不是语言问题,IMO#1和#3并不是严重问题。
评论
可以从Python 2.5和__future__ import with_statement中获得,但是我同意,我偶尔发现不幸的是,诸如if / for / print / etc之类的语句是“特殊的”而不是常规函数
– dbr
2012年9月9日在22:03
#12 楼
Python是我最喜欢的语言,因为它具有很高的表现力,但仍然可以避免犯太多错误。我还有一些让我烦恼的事情:没有真正的匿名功能。 Lambda可用于单语句功能,而
with
语句可用于在Ruby中使用代码块的许多事情。但是在某些情况下,它会使事情变得比实际情况更加笨拙。 (远没有Java那样笨拙,但仍然...)模块和文件之间的关系有些混乱。从命令行运行“ python foo.py”与“ import foo”不同。 Python 2.x中的相对导入也会引起问题。尽管如此,Python的模块仍然比C,C ++和Ruby的相应功能好得多。
显式
self
。即使我了解其中的某些原因,并且即使我每天都使用Python,但我还是会犯忘记它的错误。另一个问题是,从模块中制作一个类会变得有些乏味。显性的自我与他人抱怨的范围有限有关。 Python中最小的作用域是函数作用域。如果您按照自己的意愿将函数保持较小,那么这本身就不是问题,而且IMO常常会提供更简洁的代码。一些全局函数,例如
len
,您希望它是一种方法(实际上是在幕后)。缩进很大。不是这个想法本身,我认为很棒,但是由于这是使许多人无法尝试Python的唯一原因,因此使用一些(可选)开始/结束符号可能会更好。忽略那些人,我也完全可以适应缩进的大小。
它不是Web浏览器的内置语言,而是JavaScript。
在这些投诉中,我只是非常关注我认为应该添加到该语言中的第一个投诉。除了最后一个,其他的都比较小,如果发生的话会很棒!
评论
+1这让我想知道是否应该在一个项目可以写入datetime.now时是否写入datetime.datetime.now(),然后以一种写入方式混合两个项目的方式排除了另一个,并且肯定不会在Java中发生,如果您不了解模块的通用名称,那么在练习了两种用法和显式自我的情况下,该模块似乎将我们与文件混淆了吗?由于调用没有与函数数量相同的参数。您可能会认为VM python速度慢?
–尼古拉斯·R。
2011年9月1日下午16:19
关于您的显式self关键字问题。我可能建议为此使用一个好的python IDE吗?我知道Eclipse上的PyDev如果检测到您正在编写类,则会自动完成函数签名的self部分。
–佐兰·帕夫洛维奇(Zoran Pavlovic)
13年1月7日,下午6:42
#13 楼
Python尚未完全成熟:此时的python 3.2语言与当前分发的大多数软件包都存在兼容性问题(通常它们与python 2.5兼容)。这是一个很大的缺点,当前需要更多的开发工作(查找所需的程序包;验证兼容性;权衡选择可能更兼容的不太好的程序包;采用最佳版本,将其更新为3.2,这可能需要几天的时间;然后开始做一些有用的事情。)就像在2012年中期那样,它的弊端就不那么大了。在开发人员讨论中,我们的高级开发人员团队得出了相同的结论。
成熟度在一个主要意义上意味着团队可以使用该技术并非常快速地启动和运行,而没有隐藏的风险(包括兼容性问题) 。如今,大多数第三方软件包的第3方python软件包和许多应用程序都无法在3.2下运行。这会带来更多的集成,测试,重新实现技术本身的工作,而不是解决眼前的问题==不那么成熟的技术。
2013年6月更新:Python 3仍然存在成熟度问题。团队成员经常会提到需要的软件包,然后说“除了仅适用于2.6”(在某些情况下,我已经通过localhost套接字实现了变通方法,以将仅2.6的软件包与2.6一起使用,其余的我们的工具仅适用于3.2)。甚至纯Python Wiki MoinMoin都不是用Python 3编写的。
评论
仅当您对成熟度的定义与设计上不兼容的版本不兼容时,我才与您同意。
– tshepang
2011年7月17日在7:25
我同意python的两个不兼容的流是一个问题(尽管可以理解为什么这样做了),但是我不认为这是“成熟度”的问题。
–温斯顿·埃韦特(Winston Ewert)
2011年7月24日,0:04
从某种意义上说,成熟度意味着团队可以使用该技术并非常快速地启动和运行,而没有隐藏的风险(包括兼容性问题)。如今,大多数第三方软件包的第3方python软件包和许多应用程序都无法在3.2下运行。这将产生更多的集成,测试,重新实现技术本身的工作,而不是解决眼前的问题==不太成熟的技术。
–乔纳森·克莱恩(Jonathan Cline)IEEE
2011年7月25日17:35
然后只需使用Python2.x。您知道...每个人都在使用的版本。或阅读软件包文档2秒钟,以了解与哪个版本兼容。
–jsternberg
2011年7月25日在22:46
“仅仅因为python 3.0已经发布了一段时间并不意味着您应该使用它的版本。Python3.0和2.x正在同时开发。我希望将来我们都可以使用python 3.0,但就目前而言,使用2.x是一个很好的解决方案”->这是500个字符的表达方式:尚未成熟。
–乔纳森·克莱恩(Jonathan Cline)IEEE
2011年7月27日在2:22
#14 楼
Python的作用域已严重破坏,这使得Python中的面向对象编程非常尴尬。评论
你能给个例子吗? (我确定你是对的,但我想举个例子)
–温斯顿·埃韦特(Winston Ewert)
2010-10-28 22:36
我喜欢Python,但绝对不愿意自己动手。在对实例属性和方法的每次引用之前。就像使用Ruby一样容易,它使得无法使用Python创建DSL。
–亚当·克罗斯兰(Adam Crossland)
2010-10-29在0:05
我没有发现自我尴尬,我喜欢露骨。
–温斯顿·埃韦特(Winston Ewert)
2010-10-29在0:48
我不明白显性自我的重要意义。在C ++,Java和D中,人们经常通过约定使成员变量显式表示,例如通过在其下加上下划线为前缀。
–dsimcha
2010-10-29在1:14
在与声明不同的方法中使用self:def foo(self)但self.foo()。我发现这种混合的显式定义和隐式幕后的东西不太漂亮。
– LennyProgrammers
2010-10-29 9:19
#15 楼
我对Python的了解:面向对象的OOP(有关此问题的详细说明,请参见@mipadi的答案)
lambdas的无效实现
范围问题
标准库中的持久性集合
对嵌入式DSL的适应性较差
评论
为什么要投票?
–missingfaktor
2010-12-26 13:32
我不是拒绝投票的人,但是您能解释一下为什么您认为OO异常强大吗? Python一直都有面向对象,这是该语言的核心部分。
–丹妮丝
2011年7月15日13:58
参见@mipadi的答案。
–missingfaktor
2011年7月15日在15:40
带有链接到@mipadi的答案
– JB。
2012年9月8日在12:48
#16 楼
Python中的访问修饰符不是强制性的-使得很难编写结构良好的模块化代码。我想这是@Mason破坏范围的一部分-这种语言通常存在很大的问题。对于本来应该可读的代码,似乎很难确定在任何给定时间范围内可以和应该在什么范围内以及值将是什么-由于这些缺点,我目前正在考虑从Python语言继续。
仅仅因为“我们都同意成年人”并不意味着我们不会犯错并且在一个坚固的结构中不能更好地工作,尤其是在处理复杂项目时-缩进和毫无意义下划线似乎还不够。
评论
因此缺少访问控制是不好的……但是对任何非本地名称空间的变量写的显式作用域也是不好的?
– ncoghlan
2011年7月13日在3:25
@ncoghlan:1-该功能是许多现代语言中的标准功能,具体取决于您配置项目的方式。 2-在程序员的控制之下。 3-不确定这样做有什么用-您可以使用大多数已编译语言/ IDE的一些项目设置轻松控制范围。如果“我们都是成年人”,我们应该能够做出自己的决定,并根据自己的舒适度调整范围。
–矢量
2011年7月13日在13:21
事实是,要求“强制访问控制”的人们要求我们拿出使Python成为一种出色的粘合语言的原因之一:开发人员故意难以控制以后如何使用其代码。有多少C ++和Java模式的样板仅用于解决强制访问控制?我绝对可以理解,出于这些原因,人们选择不使用Python,但是静态强制绝不能替代严格的测试。
– ncoghlan
2011年7月14日在5:02
@ncoghlan-对我来说,关于Python的伟大之处在于语法的优雅性和简洁性-表现力。正如我所说的那样,范围界定与程序员弄乱他们不该做的事情无关,而与代码结构和组织无关。因此,“同意成年人”的概念尚无定论。我从事复杂的项目,而不是简单的实用程序和脚本-代码必须经过仔细的模块化和结构化-访问修饰符是确保实现这一目标的最重要方法之一。
–矢量
2011年7月14日在6:56
代码审查,培训和耦合分析等。对我来说,强制访问控制与静态类型属于同一类:它们确实有助于在正确性上提供一些额外的信心(但不足以避免需要进行广泛的测试),但是却会提高开发效率。 (在实践上,类属性访问控件也不适合Python的对象模型,因为方法只是从类检索的普通函数。类的“内部/外部”边界实际上并不存在,因此不能强制执行)
– ncoghlan
2011年7月14日在7:20
#17 楼
性能不好,但是使用pypy可以提高性能,
GIL阻止使用线程加速代码(尽管通常这是过早的优化),应用程序编程,
,但是它具有一些重要的兑换功能:嵌入python解释器),
可读性强,
很容易学习,
有据可查,
电池确实包含在内,它的标准库很大,并且pypi包含模块对于几乎所有事物,
它都有一个健康的社区。
评论
是什么激发了我提到优势的呢?问题的问题。无论如何,您的意思是它仅对应用程序编程有用吗?还有什么其他程序?具体是什么不好?
– tshepang
2010-12-30 13:27
我列出了优点,因为我认为它们胜过缺点。您是否曾经尝试在python中实现Linux内核模块。
– dan_waterworth
2010-12-30在16:34
#18 楼
我确实喜欢python,想到的第一个缺点是注释掉if myTest():
之类的语句时,您必须更改整个执行的块的缩进,而不必使用C或Java。实际上,在python中,而不是注释掉if子句,我开始以这种方式注释掉它:`if True:#myTest()这样,我也不必更改以下代码块。由于Java和C不依赖缩进,因此使用C和Java可以更轻松地注释掉语句。 评论
您是否会认真编辑C或Java代码以更改某些代码的块级别而不更改其缩进?
–本
2011年7月24日在6:35
@Ben临时,是的...
–替代
2011年7月24日14:36
@ben在这里一样。
–克里斯托弗·马汉(Christopher Mahan)
2011年7月25日在18:11
我使用的技巧是将if something()更改为False和something()。另一个技巧是使用多行字符串“注释掉”。
– Martin Vilcans
2011年7月25日在22:23
@马丁当然!如果错误...
–克里斯托弗·马汉(Christopher Mahan)
2011年7月25日在23:40
#19 楼
多重调度不能很好地与已建立的单调度类型系统集成,并且性能也不高。元数据密集型操作。我的同事花了25万个核心小时的时间才将Python(带有numpy,mpi4py,petsc4py和其他扩展模块)加载到65k内核上。 (该模拟提供了重要的新科学成果,因此值得这样做。但是,当燃烧一桶以上的油来装载Python时,这是一个问题。)无法进行静态链接迫使我们不得不做出巨大的扭曲来获取合理的大规模加载时间,包括修补libc-rtld以使dlopen
执行集体文件系统访问。评论
哇,技术水平很高,您有与此主题相关的参考资料,示例,博客文章或文章吗?我想知道我是否会在不久的将来遇到这种情况。
– Vincent
2012年9月8日20:00
Aron在SciPy 2012上发表了演讲。dlopen的东西在我们的collfs库中。该存储库还包含受Asher Langton的路径缓存启发的其他zipimport技巧。我们正在致力于更好的发行和论文。
–杰德
2012年9月8日于20:31
#20 楼
很多一堆非常主流的第三方库和广泛使用的软件不是pythonic。一些示例:soaplib,openerp,reportlab。 Critique不在范围之内,它在那儿被广泛使用,但它使python文化令人困惑(这打击了座右铭:“应该有一种-最好只有一种-显而易见的方式”)。已知的pythonic成功(例如django或trac)似乎是一个例外。但是要掌握它,您必须深入了解解释器(解释python代码的顺序等)。它并没有广为人知和使用(或正确使用),而类似的黑魔法(如C#泛型)在概念上更令人费解(IMHO)似乎按比例更广为人知和使用。线程模型,您必须对python有相当的经验,因为没有全面的规范。您只知道有效的方法,可能是因为您阅读了口译员的资料或经验丰富的怪癖,并发现了解决方法。例如,只有强引用或弱引用,而不是Java的软引用和幻象引用。 Java有一个用于垃圾回收的线程,而对于何时在python中进行垃圾回收却没有正式的答案。您可以观察到,如果不执行任何python代码,则不会发生垃圾回收,并得出结论,在尝试分配内存时有时可能会发生垃圾回收。当您不知道为什么为什么不释放锁定的资源时可能会很棘手(我的经验是在freeswitch中使用mod_python)。成为狂热分子,精英人士或狂人并不是蟒蛇文化的一部分。
评论
+1。内存和线程模型的规范就正确了。但是FWIW,线程上的Java垃圾收集器(以及有关GC的大多数其他内容)本身并不是Java语言或VM规范的一个方面,而是特定的JVM实现的问题。但是,主要的Sun / Oracle JVM在GC行为和可配置性方面得到了广泛的记录,以至于整本书都出版了有关JVM调优的书籍。理论上,不管语言规范如何,都可以用相同的方式记录CPython。
–安德鲁·扬克(Andrew Janke)
2012年11月26日在3:44
#21 楼
奇怪的OOP:
len(s)
至__len__(self)
和其他“特殊方法” 可以从其他特殊方法(
__add__
和__iadd__
和+
和+=
)self
作为第一个方法参数您可以忘记调用基类构造函数
没有访问修饰符(私有,受保护的...)
没有常量定义
自定义类型没有不变性
GIL
性能差,导致Python和C混合使用以及构建麻烦(查找C库,平台依赖项.. 。)
错误的文档,尤其是第三方库中的文档
Python 2.x和3.x之间的不兼容
代码分析工具较差(与为静态类型化语言(如Java或Java或Java)提供的代码分析工具相比) C#)
评论
我个人认为2.x和3.x之间的不兼容性是Python的最大优势之一。当然,这也是一个缺点。但是,开发人员敢于打破向后兼容性的勇气也意味着他们不必无休止地进行繁琐工作。更多的语言需要这种大修。
–康拉德·鲁道夫(Konrad Rudolph)
2012-09-10 13:39
#22 楼
“不可变性”并不是它的强项。 AFAIK数字,元组和字符串是不可变的,其他所有内容(即对象)都是可变的。将其与诸如Erlang或Haskell之类的功能语言(其中所有内容都是不可变的)(至少默认情况下)进行比较。但是,不可变性确实通过并发*闪耀,这也不是Python的强项,因此至少这是必然的。是的,喜欢FP的人,我知道即使没有并发性,不变性也很好。))
#23 楼
我很想拥有明确的并行结构。通常,当我编写诸如[ f(x) for x in lots_of_sx ]
这样的列表理解时,我不在乎元素的处理顺序。有时,我什至都不关心它们的返回顺序。 。
评论
//生成一堆线程//将队列que传递给所有线程que.extend([x对于lots_of_sx中的x]] que.wait()#等待线程处理所有lots_of_sx。
–佐兰·帕夫洛维奇(Zoran Pavlovic)
2013年1月7日在7:02
评论
我认为这是一个有用的主观问题,将其关闭将很可惜。这里似乎有一个python-fanboy只是对所有反python答案都投了反对票。
@TMN:仍然将空白视为标记,只是不返回它们-这也正是Python的语法。
@Roger:关于SO的约定是评论下注。由于这是一个主观意见的网站,因此,我认为没有理由进行投票。没有评论。所以,我坚持我的“呼唤”。
@zvrba:与往常一样,投票仍然意味着“无用”。