Python太烂了!

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

原因1版本之间不兼容

安装Linux后那么它很可能默认会安装多个版本的Python可能有Python2和Python3甚至更多零零碎碎的版本如3.5或3.7。

这是有原因的Python3与Python2不完全兼容一些其他版本在这方面的缺陷也足够明显——向后兼容性不足backwards compatibility也称为向下兼容性。

所以Ubuntu同时安装了Python2和Python3因为这些版本的核心功能是不同的。

缺乏向后兼容和分离版本通常是走向衰败的预警。Commodore创建了第一台家用电脑要远早于IBM PC或Apple之前。但Commodore PET与随后的Commodore CBM计算机并不兼容而CBM与VIC-20Commodore-64Amiga等也不兼容。因此用户要么花费大量时间将代码从一个平台导到另一个平台要么就直接放弃了这个平台——Commodore就是前车之鉴。当用户选择放弃平台时它就注定会消失。

同样Perl曾经很受欢迎。但是当Perl3问世时它并没有完全向后兼容Perl2的代码。接下来是Perl4。当Perl5问世时很多人选择转向使用其他更稳定的编程语言。所以今天只有一小部分人还在积极使用Perl来维护现有的Perl项目而其他任何基于Perl的重大新项目再也没有出现过。

同样Python为每个版本设计了不同的代码孤岛。社区一直拖拽着这些旧版本所以你最终也只能得到那些旧的、过时的Python代码因为没有人愿意花时间将它导到最新版本上。

据我所知没有人在Python2上创建新的代码但我们还让它苟延残喘着因为没人将所需的代码导到Python3.x. 在官方Python网站上这些文档被主动维护并可用于Python 2.7、3.5、3.6和3.7——因为他们无法放弃旧代码。Python就像编程语言的僵尸——行尸走肉般向前走。

原因2安装太太太太麻烦了

通常来说你直接apt、yum、rpm后得到就是最新稳定版。

但你如果'apt-get install python'就不知道是什么版本可能与你需要的所有代码都不兼容。所以你在安装的时候需要指定Python版本。

有一个项目需要用Python3.5当时最新的版本然而我的电脑上最终安装了一大堆版本Python2、Python2.6、Python3和Python3.5。两个来自操作系统一个为了项目安装一个是因为我安装了一些不相关的软件。

尽管它们都是“Python”但它们并非完全相同。

如果你想安装Python的软件包你应该使用“pip”Pip代表“Pip Installs Packages”。但是由于系统上有许多版本的Python你必须记住使用正确版本的pip。否则'pip'可能会运行'pip2'而不是你需要的'pip3.7'。如果名称不存在你需要指定pip3.7的实际安装路径。

我被一个朋友告知我需要配置环境以便所有东西都能使用Python 3.5。这种方法的确很有效但没有持续多久因为我开始了另一个需要Python 3.6版本的项目。两个并发项目有两个不同版本的Python——emmmm这有点一言难尽吧。

pip安装程序将文件放在用户的本地目录中。你不能使用pip来安装系统范围的库并且Gawd会阻止你犯下运行'sudo pip'的错误因为这会搞砸整个电脑

顺便说一句是谁维护这些pip模块答案是社区。也就是说没有明确的所有者也没有强制性的责任所属。今年早些时候一个版本的PyPi有一个后门发生了SSH凭据盗窃但我对此一点都不惊讶因为社区存储库根本不值得相信。出于同样的原因我也不使用Node.js和npm。

原因3令人头疼的语法问题作用域使用空格导致可读性差

我是可读代码的坚定信徒。乍一看Python似乎非常易读而当你开始制作大型代码库这种易读性就会减弱了。

其他编程语言像C, Java, JavaScript, Perl, and PHP用{} 来表示作用域List用()。Python用空格。如果你需要给一个复杂的代码定义一个作用域然后你缩进了下面几行代码当缩进终止后作用域就终止了。

Python手册说你可以使用任意数量的空格或制表符来定义范围。但是每次缩进都要用四个空格如果要缩进两次以进行嵌套那就得使用八个空格

Python社区已经对这个术语进行标准化尽管它没出现在Python手册中。文档中的示例说可以使用TAB、“TAB+1空格”等等。但是社区却对4个空格有着丧心病狂的偏执因此除非你打算永远不向其他任何人展示你写的代码否则每个缩进都要使用四个空格。

当我第一次看到Python代码时我认为使用缩进来定义范围似乎是个好主意。事实上我太天真了这简直是一个天大的缺点。

深度嵌套是可以进行的但每行代码会变得很宽不得不在文本编辑器中换行。长函数和长条件操作都可能让开始与结束变得难以匹配。我可怜那些错误计算空格数量比如只输了3个空格而不是四个的人因为这样的错误需要数小时进行调试和追踪。

我debug代码习惯没有缩进这样我就可以快速浏览代码并在完成后轻松识别和删除debug代码。

但是用Python呢缩进错误的话都会报错。

原因4特立独行的加载库方式

大多数编程语言都有一些方法可以包含其他代码块。对于C它是“#include”。对于PHP有'include''include_once''require'和'require_once'。而对于Python则是“import”。

Python的import允许导入整个模块、模块的一部分或模块中的特定功能。但查找导入代码块的方法却很麻烦。使用C直接看/usr/include/*.h就行了。但用Python最好使用'python -v'列出所有位置然后搜索该列表中每个目录和子目录中的每个文件。这真的很麻烦。

导入功能还允许用户重命名导入的代码它们基本上定义了一个命名空间。乍一看这似乎很不错但这最终会影响可读性和长期支持。重命名模块非常适合小脚本但对于大程序来说真的很糟糕。这样的操作“import numpy as n”应该被打死。

但这不是最糟糕的部分。对于大多数语言包含代码真的只意味着包含代码。而一些语言如面向对象的C ++则可以执行代码。类似地一些PHP代码可能会定义全局变量因此一项import可以运行代码但这通常被认为是一种不好的做法。相比之下许多Python模块包含在导入期间运行的初始化函数。你不知道什么在运行你不知道它在做什么你甚至都没察觉到。除非存在命名空间冲突否则在这种情况下你需要花很长时间来查找原因。

原因5关键字和库命名“独树一帜”

在其他所有编程语言中数组都称为“array”。在Python中数组被称为“list”。在其他语言中关联数组有时称为'hash'Perl但Python里叫做“dictionary”。 Python似乎没有使用在计算机和信息科学领域的常用术语。

然后是库的名称。看看这些名字吧PyPy、PyPi、NumPy、SciPySymPy、PyGtk、PygletPyGame ...是的前两个名称发音一模一样但是它们的功能和用途有很大区别。我知道“py”代表Python。但这两个字母就不能固定在库的开头或是末尾吗

而且一些常见的库并没有沿用这个所谓的“Py”命名约定。比如matplotlib、nose、Pillow和SQLAlchemy。虽然从一些命名上能够看出库的一些功能比如“SQLAlchemy”包含SQL所以它可能是一个SQL接口但很多名称只是随机化的单词。如果你事先并不知道“BeautifulSoup”是干什么用的你能从名称中看出它是一个HTML / XML解析器吗顺便说一句BeautifulSoup库的说明文档很完备非常易于使用。如果每个Python模块都这么好用我也不会在这里吐槽这么多。但遗憾的是这只是个例外而不是常态。大多数Python库的文档都烂的要死。

总的来说我认为Python对库的命名非常混乱缺乏一致性的原则。我总觉得开源项目的命名都存在这种规则混乱的问题。除非你了解这个项目否则你从项目名字上根本看不出来。除非你知道要找的是什么否则你很可能永远都无法找到想找的东西。从大多数Python库的命名上看我现在更加确信这个观点了。

原因6其他“独树一帜”之处略多

每种语言都有它的怪癖。在C语言中使用&和*来访问地址空间和值是奇怪的命名法。C也有“++”和 --"这样的变量增减控制方式。在Bash语言中当引用括号和正则表达式的句点等特殊字符时需要使用反斜杠。

JavaScript存在兼容性问题并非每个浏览器都支持所有有用的功能。但是Python比我见过的任何其他语言的奇怪之处更多。以字符串为例

•在C中对字符串使用双引号对字符使用单引号。

•在PHP和Bash中两种类型的引号都可以用于字符串。但是使用双引号时可以在字符串中嵌入变量。相比之下使用单引号括起来的字符串属于文字。任何类似嵌入式变量的名称都不可扩展。

•在JavaScript中单引号和双引号之间确实没有区别。

•在Python中单引号和双引号之间没有区别。但是如果想让字符串跨行则需要使用三引号“”“string”“”或“''string'''。如果想使用二进制文件那么你需要用bb'binary'或rr'raw'来优先选择字符串。有时还需要使用strstring进行字符串转换或使用string.encode'utf-8'将其转换为utf8。

如果你认为=、==和===这些符号PHP和JavaScript中有点怪那么等你在Python中使用引号时再说吧。

原因7赋值方式怪异

大多数编程语言都按值传递函数参数。如果函数改变了值则结果不会传递回调用代码。但Python不一样。 Python默认使用pass-by-object-reference参数执行函数。这意味着更改源变量可能最终会改变值。

这是面向程序、面向函数和面向对象编程语言之间的重大差异之一。如果每个变量都是通过对象引用传递的而且对变量的任何更改都会导致其他所有地方的变量值变化那么其实也可以全部使用全局变量来处理所有内容。使用不同的名称调用同一个对象不会更改对象的值因此实际上该对象就是全局的。C语言程序员有句老话全局变量是邪恶的不应该使用。

在Python中必须按值传递变量。“a = b”只是为同一个对象空间指定另一个名称并不会将b的值赋到a中。如果要赋值则需要使用copy函数。通常格式是“a = b.copy”。但是请注意我说的是“通常”。并非所有数据类型都能够这样赋值部分功能可能不完整。这时需要使用一个名为“copy”的独立库“a = copy.deepcopyb”。

原因8本地程序命名易混乱

根据使用的库或函数来命名程序是一种常见的编程技术。比如我正在使用名为“libscreencapture.so”的C语言库测试屏幕捕获程序我调用的程序可能会命名为“screencapture.c”编译后命名为“screencapture.exe”。

如果使用CJavaJavaScriptPerlPHP等语言这种命名方式很好用因为程序语言可以很容易地将资源库与本地程序区分开来因为彼此的路径是不同的。但是如果用的是Python永远不要这样命名。

为什么 Python总是假定用户首先要导入本地代码。如果我有一个名为“screencapture.py”的程序使用“importscreencapture”那么它将导入自己而不是系统库。至少本地程序需要命名为“myscreencapture.py”才能避免这种错误。

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: python