频频霸榜的Python,竟遭开发者嫌弃!
在刚刚过去的 2018 年里,要说最热门的科技领域是哪一个?毋庸置疑的是,人工智能必排在前列;而要论编程语言界,最流行的编程语言是谁?那非 Python 莫属。2018 年 8 月,根据一年一度的 IEEE Spectrum 编程语言来看,Python 一路高歌猛进,位居 48 种编程语言之首。不仅如此,在本月最新的 TIOBE 排行榜中,Python 再次超越 C++,位居排行榜前三甲,其受欢迎程度不言而喻,但就在此时,Python 却惨遭开发者嫌弃了,而这究竟是怎么一回事?
作者 | Neal Krawetz
译者 | 弯月
责编 | 屠敏
来源 | CSDN(ID:CSDNnews)
以下为译文:
有时候我会跟一些搞技术的朋友们出去吃饭,当然我们会愉快地讨论技术。我们讨论自己项目、讨论新鲜事、讨论各种技术问题。最终不可避免地会讨论到编程语言。有人就会说“我又得改 Java 代码了。我恨 Java。”(抱歉了 Kyle……)(其实十多年前我们就给 Kyle 起了个绰号“Java 小子”。)另一个人就会谈起某个古老的无所不包的 Shell 代码,那段代码无人敢碰。
至于我,嗯……我的话一出口众人都惊呆了:我讨厌 Python。我讨厌它是有原因的。如果我能用 C 重写某段 Python 代码,那我一定会重写的。
但我吼完之后,Bill 幽默地补刀:“那你内心里是怎么看 Python 的,Neal?”所以就有了这篇文章。谨以此文献给 Bill。
下面是我列出的“8 个理由说明 Python 很糟糕”。
版本
默认的 Linux 安装很可能会带有多个版本的 Python。很可能会同时拥有 Python 2 和 Python 3,而且很可能同时拥有不同的子版本,如 3.5 和 3.7。理由是:Python 3 不能与 Python 2 完全兼容。即使一些子版本号也会造成无法后向兼容。
我不反对给语言添加新功能,甚至退役一些旧版本也无所谓。但是,不同的软件需要不同的 Python。我给 Python 3.5 编写的代码不能在 Python 3.7 上正常运行,除非我专门将其移植到 3.7。许多 Linux 开发者都认为移植不值得,所以 Ubuntu 就同时带有 Python 2 和 Python 3,因为不同的核心功能需要不同的 Python 版本。
缺乏向后兼容和版本之间的割裂通常是死亡的信号。Commodore 是世界上最早制造家用电脑的厂商之一(远在 IBM PC 和苹果之前)。但 Commodore 的 PET 没法与后继的 Commodore CBM 电脑兼容。而且,CBM 也不兼容 VIC-20、Commodore-64、Amiga 等。所以,你只能花大把时间把代码从一个平台移植到另一个平台,否则就要完全放弃那个平台。(现在 Commodore 在哪儿?它早就因为用户放弃它的平台而死了。)
同样命运的还有 Perl。Perl 曾经非常流行。但 Perl 3 问世时,它与很多 Perl 2 代码都不兼容。社区对此意见很大,只有好的代码得到了移植,其他代码都被抛弃了。然后 Perl 4 出现时又发生了同样的事情。Perl 5 出现时,很多人干脆换到了其他更稳定的编程语言。现在,只有很少一部分人仍然在使用 Perl 来维护现有的 Perl 项目。已经没有任何新项目使用 Perl 了。
同样,Python 的每个版本的代码也都是不一样的,社区也不得不维护旧的版本。因此就要不断维护一大堆陈旧已失去活力的 Python 代码,因为没人想把它们移植到新版本。据我所知,现在没有人在 Python 2 上写新代码,但现有的 Python 2 又不得不维护,因为人们不愿意将它们移植到 Python 3。在 Python 的官方网站上,Python 2.7、3.5、3.6 和 3.7 的文档都在维护中,因为还有旧代码在使用这些版本,他们没办法放弃这些版本。Python 就像编程语言中的百足之虫,死而不僵。
安装
绝大多数软件包都可以通过 apt、yum、rpm 或某种安装方式获得最新的代码。而 Python 则不一样。你无法知道 apt-get install python 会给你装什么版本,很可能这个版本跟你的代码都不兼容。
所以,必须选择你所需版本的 Python 来安装。我参与过的一个项目使用的是 Python,但必须使用 Python 3.5(当时的最新版本)。最后我的电脑上安装了 Python 2、 Python 2.6、Python 3 和 Python 3.5。两个是操作系统自带的,一个是为项目安装的,另一个来自我安装的某个不相关的软件。虽然它们都是 Python,但并不是完全一样。
要想给 Python 安装软件包,应该使用“pip”命令。(pip 的意思是“PIP Install Packages”,因为有人觉得递归的缩写很有意思。)但由于系统上有多个版本的 Python,你必须要注意使用正确版本的 pip。否则,pip 可能运行的是 pip 2 而不是你需要的“pip 3.7”。(如果 pip 3.7 这个命令不存在,你还得指定正确的路径。)
有个团队成员建议我,我应该配置自己的环境,这样一切都能使用 Python 3.5 的版本。这种方法很好,但后来我的另一个项目需要 Python 3.6 就出现麻烦了。两个并行的项目使用了不同版本的 Python……嗯,这还不够迷惑。(表示讽刺的表情是什么来着?)
pip 安装程序会把文件放到用户的本地目录中。系统范围上的软件包不能使用 pip 安装。而且你也不能使用 sudo pip,因为那会搞乱你整个电脑!因为使用 sudo 会在整个系统级别安装软件,一些软件会安装到错误的 Python 版本,一些会留在你的主目录中但却属于 root,导致以后的非 sudo pip 命令由于权限问题而出错。所以不要使用 sudo pip。
另外,谁负责维护这些 pip 模块?是社区。也就是说,没有固定的拥有者,也没有强制的保证或审计。今年早些时候,某个版本的 PyPI 被发现有个后门,会盗取 SSH 密码。这种事情根本不奇怪。(同样的原因我也不用 Node.js 和 npm,我不相信他们的社区软件仓库。)
语法
我极其推崇代码的可读性。初看起来,Python 代码似乎可读性很高。没错,不过条件是你不要用它来开发大型代码。
绝大多数编程语言都有某种标识来表明作用域——即函数何时开始何时结束,动作包含在一个条件语句中,变量定义的范围,等等。不论是 C、Java、JavaScript、Perl 还是 PIP,大家都使用{ ... } 为复杂的代码定义作用域,而 Lisp 使用(...)定义作用域。Python 呢?Python 使用空格。如果需要为一段复杂的代码定义作用域,就必须要缩进接下来的几行。缩进结束就表明作用域的结束。
我第一次看到 Python 代码时,我认为使用缩进定义作用域是个不错的想法。但是,这种方式有个巨大的缺点。这种方式可以写出很深的嵌套,但代码行也会变得很宽,导致在文本编辑器中折行。长的函数和长的条件动作很难找出作用域的开始和结束。而且,只要你数错了空格,或者在某行开头放了三个空格而不是四个空格,那你需要花上几个小时的调试才能找到问题所在。
在其他语言中书写调试代码时,我习惯不放任何缩进。这样我就能迅速浏览到代码,并在调试结束之后很容易地找到调试代码并删掉。但用 Python 呢?任何缩进不正确的行都会导致缩进错误。也就是说,调试代码必须混合到正式代码中。
包含
大多数编程语言都有一些方法可以包含其他代码块。C 语言有“#include”。PHP有'include','include_once','require'和'require_once'。而 Python 有“import”。
Python 的导入允许包括整个模块,模块的一部分或模块中的特定功能。想知道哪些东西可以导入,并没有什么直观的办法。使用 C,你可以查看 /usr/include/*.h。但是用 Python?最好使用 'python -v' 列出它看起来的所有位置,然后搜索该列表中每个目录和子目录中的每个文件。我曾经看到我喜欢 Python 的朋友 grep 标准模块来寻找他们想要导入的东西。这是真事。
导入功能还允许用户重命名导入的代码。它们基本上定义了一个自定义命名空间。乍一看,这似乎很不错,但最终会影响可读性和长期支持。重命名模块非常适合小脚本,但对于长程序来说真的很糟糕。使用 1-2 字母命名空间的人,例如“import numpy as n”应该拖出去枪毙(或强制将其所有代码转换为 Perl 5)。
但这不是最糟糕的部分。对于大多数语言,include 一段代码只会包含代码。一些语言(如面向对象的 C ++)会在存在全局构造函数的情况下执行代码。类似地,一些 PHP 代码可能会定义全局变量,因此导入可以运行代码——但通常人们认为这不是一种好做法。相比之下,许多 Python 模块包括在导入期间运行的初始化函数。你不知道哪部分代码在运行,你不知道它在做什么,你甚至可能都注意不到。哦,有一种情况你会注意到——那就是出现命名空间冲突的时候,在这种情况下,你需要花很多时间来追踪原因。
命名法
在其他所有语言中,数组都称为“array”。在 Python 中,它们被称为“list”。关联数组有时称为'hash'(Perl),但 Python 称之为'dict'。 Python 似乎没有使用在计算机和信息科学领域的常用术语。
然后是库的名称。 PyPy,PyPi,NumPy,SciPy,SymPy,PyGtk,Pyglet,PyGame ...(是的,第一个和第二个的读音相同,但是它们是完全不同的东西。)我知道'py'表示 Python。但 py 放在开头还是结尾能不能有个固定的写法呢?
一些常见的库只是放弃了类似双关语的“Py”命名约定。这包括 matplotlib,nose,Pillow 和 SQLAlchemy。虽然一些名称可能暗示库的目的(例如,“SQLAlchemy”包含 SQL,所以它可能是一个 SQL 接口),但其他名称只是随机的单词。如果你不知道“BeautifulSoup”是干什么的,你能从名称中看出它是一个 HTML / XML 解析器吗? (顺便说一句,BeautifulSoup 有很好的文档和易于使用。如果每个 Python 模块都是这样的,我不会抱怨太多。不幸的是,这并不是常态。大多数 Python 库的文档写得都很差。 )
总的来说,我将 Python 视为具有可怕且不一致的命名约定的库的集合。我有一个常见的抱怨,开源项目通常有可怕的名字。除非你知道这个项目,否则你永远不知道它的名字是什么。除非你知道要寻找什么,否则只能期待于偶然遇到某个别人提起的库了。而且大多数 Python 库都强化了这种负面的批评。
怪癖
每种语言都有它的怪癖。C 语言使用&和*来访问地址空间和值的做法很奇怪。 C 还有使用 ++ 和 -- 来表示递增/递减的快捷方式。在 Bash 中,当引用括号和正则表达式的句点等特殊字符时,就会出现“何时使用反斜杠”的问题。 JavaScript 存在兼容性问题(并非每个浏览器都支持所有有用的功能)。然而,Python 比我见过的任何其他语言都有更多怪癖。就拿字符串来说:
C 语言中双引号表示字符串,单引号表示字符。
PHP 和 Bash 中,任何引号都可以用来表示字符串。但是,双引号可以在字符串中嵌入变量。与此相反,单引号字符串是单纯的字符串,任何类似嵌入式变量的名称都不会扩展。
在 JavaScript 中,单引号和双引号之间没有任何区别。
Python 中的单引号和双引号之间也没有区别。但是,如果您希望字符串跨越行,则需要使用三引号"""string"""或“''string'''。如果你想使用二进制文件,那么你需要用 b(b'binary')或 r(r'raw')来指示字符串的形式。有时你需要使用 str(string) 将字符串转换为字符串,或使用 string.encode('utf-8') 将其转换为 utf8。
如果你认为 =,== 和 === 在 PHP 和 JavaScript 中有点奇怪,那你应该看看 Python 中的引号使用方法再下结论。
对象的引用传递
大多数编程语言都用值方式传递函数参数。如果函数改变了值,则改变不会影响到调用的代码。但正如我已经解释过的那样,Python 在这方面依然与众不同。 Python 默认使用引用方式传递参数。这意味着更改参数可能会导致原始值的改变。
这是过程式编程、函数式编程和面向对象编程语言之间的重大差异之一。如果每个变量都是通过对象引用传递的,并且对变量的任何更改都会影响到任何使用该变量的地方,实际上就相当于一切都使用了全局变量。针对一个变量使用不同的名称实际上都是同一个对象,所以跟使用全局变量没什么区别。C 程序员很久以前就知道,全局变量是邪恶的,不应该被使用。
Python 中要想按值传递变量就必须使用额外的方式。简单地写下“a = b”只会给同一个对象起另一个名字,而不会将 b 的值复制到 a 中。如果你确实要复制该值,则需要使用复制功能。通常是用“a = b.copy()”。但是请注意我说的是“通常”。并非所有数据类型都支持“复制”的原型,还有可能复制功能不完整。在这些情况下,你必须使用一个名为“copy”的独立库,即“a = copy.deepcopy(b)”。
局部命名
根据使用的库或函数对程序进行命名,是常见的编程技巧。例如,如果我要对使用某个名为"libscreencapture.so”的库的截屏程序进行测试,我会把我的程序叫做“screencapture.c",并编译成“screencapture.exe”。
gcc -o screencapture.exe screencapture.c -lscreencapture
这个技巧能在 C、Java、JavaScript、Perl、PHP 等语言中正确使用,因为语言能区分出资源库文件和本地的程序,因为它们的路径是不一样的。但在 Python 却不行。为什么?Python 认为你想优先导入本地文件。如果我有个程序叫做“screencapture.py”,它要执行“import screencapture”,那么它将导入自己,而不是导入系统库。至少,你得把本地的库命名为“myscreencapture.py”之类的才行。
也并非一无是处
Python 是个非常流行的语言,有很多拥护者,我甚至有一堆朋友真的很喜欢 Python。多年以来,我一直与他们讨论这些问题,每次他们都表示同意。他们同意这些都是 Python 的问题,只是他们觉得这些还不足以让他们失去对 Python 的兴趣。
我的朋友经常提起 Python 那些非常酷的函数库。我也同意,某些函数库非常有用。例如, BeautifulSoup 就是我用过的最好的 HTML 解析器之一,NumPy 简化了多维数组和复杂的数学计算,TensorFlow 在机器学习方面非常有用。但我不会只因为 TensorFlow 或者 SciPy 就用 Python 编写一个大而全的程序。我不会放弃可读性和可维护性,这样做不值得。
通常,我在批评某个东西时也会写一些正面的东西。比如,我的博客上“开源很糟糕”后面写了一篇“开源很不错”,批评完 ffmpeg 的局限性之后也会特别提到它是最优秀的视频处理库。但 Python 我写不出优点列表来,因为我真的觉得它太糟了。
原文:
https://www.hackerfactor.com/blog/index.php?/archives/825-8-Reasons-Python-Sucks.html
作者:Neal Krawetz,在 Texas A&M University 获得计算机科学的博士学位,创立了 HackerFactor Solutions,专注于非传统的计算机法医学、在线评测、网络和计算机安全等。
本文为 CSDN 翻译,如需转载,请注明来源出处。
公开课预告
◆
强化学习
◆
本课程是一次理论+实战的结合,将重点介绍强化学习的模型原理以及A3C模型原理,最后通过实践落实强化学习在游戏中的应用。
推荐阅读:
刘铁岩谈机器学习:随波逐流的太多,我们需要反思
清华首批7门标杆课程,到底有多牛?
老程序员肺腑忠告:千万别一辈子靠技术生存!
Java JDK 收费,Android 也坐不住了,程序员们该咋办?
程序员有话说|外包程序员,混得最差劲
IPFS 深入浅出:从《黑镜》说起
云计算的概念 - 初识云计算知识专栏(1)
这个用Python编写的PDF神器你值得拥有!
春运抢票靠加速包?试试这个Python开源项目吧
相关文章:

#每天一种设计模式# 观察者模式
系统常常会出现这种情况: 每一个部分需要知道整体的状态。比如Excel中,当你修改了一个单元格的值,可能横列的sum需要改变,纵列的sum需要改变,根据这个单元格做的图需要改变,是否被修改的按钮需要激活... 如…

el-input怎么绑定回车事件
在 Vue 2.0 中,为自定义组件绑定原生事件必须使用 .native 修饰符:<el-input v-model"queryForm.skuName" placeholder"请输入商品名称" keyup.enter.native"skuNameSearch"></el-input> 转载于:https://www.…

DOS命令大全(经典收藏)
http://wuhua.javaeye.com/blog/32374 net use \\ip\ipc$ " " /user:" " 建立IPC空链接 net use \\ip\ipc$ "密码" /user:"用户名" 建立IPC非空链接 net use h: \\ip\c$ "密码" /user:"用户名" 直接登陆后映射对…

Ruby Metaprogramming
Ruby使用者对attr_accessor一定不会陌生。 class Aattr_accessor :num end 等效于: class Adef numnumenddef (value)num valueend end 在类的定义中,attr_accessor定义了num的读写方法,只用了一行代码就生成了两个实例方法,很…

四川大学线下编程比赛第一题:数字填充
四川大学线下编程比赛第一题:数字填充公布公司:有 效 期:CSDN 2014-09-27至2015-09-26 难 度 等 级:答 题 时 长:编程语言要求:120分钟C C Java C#题目详情peter喜欢玩数字游戏。但数独这种游戏对他来说太简…

Google AI骗过了Google,工程师竟无计可施?
作者 | 若名 出品 | AI科技大本营 如果你通过 Google 搜索购买演唱会门票或者注册论坛账号,系统会提示你必须点击几个图框、音频或者移动鼠标等操作来确认是人类在操作验证而不是机器人。 其背后的验证机制就是 CAPTCHA(验证码),…

用高中数学理解AI “深度学习”的基本原理
本文作者尚俊霖,全职产品经理,业余自学机器学习。最近开始写硬核科普,欢迎关注公众号欠拟合(ID:Underfit)。Google 研发了十年自动驾驶后,终于在本月上线了自动驾驶出租车服务。感谢“深度学习”技术&#…

Linux I2C工具查看配置I2C设备【转】
转自:http://blog.chinaunix.net/uid-26895763-id-3478882.html 在處理音訊相關的問題時,我通常會找個方法來讀寫codec中register的值。幸好linux上也有這樣的工具 – i2c tools。先到lm-sensors下載soure code,然後cross compile成arm的執行…

Ruby之类定义
介绍几种不常见的类定义方法: 1. Struct PersonStruct.new(:name,:age,:sex)pPerson.new("liyuchun")puts p Struct生成一个仅仅包含数据属性的类。但是你可以在这个类的基础上扩展: PersonStruct.new(:name,:age,:sex)class Persondef …

引用 引用 引用 学会求知 学会共处 学会做人 学会做事
◆学历不等于能力和水平,学校学到的在社会能用上的只有15%,而在社会能学到85%。◆世上很多发生的事必有其原因,必有其结果,必有其收获。◆心态归零,天道酬勤。◆老板是私营企业家,赚了小钱是自己的…

python写一个通讯录step by step V3.0
python写一个通讯录step by step V3.0 更新功能: 数据库进行数据存入和读取操作 字典配合函数调用实现switch功能 其他:函数、字典、模块调用 注意问题: 1、更优美的格式化输出 2、把日期换算成年龄 3、更新操作做的更优雅 准备工作 db准备…

#每天一种设计模式# 模板方法
《松本行弘的程序世界》对模板方法(Template method)的说明非常清晰: 在父类的一个方法中定义算法的框架,其中几个步骤的具体内容则留给子类来实现。 比如一个用于公司欢迎同事的程序: class Adef initializename "jinbin"word …

如何更好地玩转GitHub?
本文作者黄昱俊,国资企业投资部总经理,主要负责投资部门建设、投资流程管理、投后资源管理。历经10年,从医疗器械研发工程师到投资管理的蜕变,业余尝试ETF量化投资。 本文介绍如何在GitHub上更新Fork以及PullRequest给源项目。 在…

System Center Data Protection Manager 2007补助说明
在 DPM 服务器上配置 Windows 防火墙 1. 在 Control Panel(控制面板)中,单击 Windows Firewall(Windows 防火墙)。2. 在 General(常规)选项卡中,验证是否已开启 Windows 防火墙&am…

可伸缩系统的设计模式(译)
Ricky Ho在他的博客中分享了该文章,该文章是一个简单的概括分享,详细的可以参见他博客的其它详细文章。下面主要是意译。 1、Load Balancer:负载均衡 – 由分发者来决定哪个工作者处理下一个请求,这种决定可以基于不同的策略。 “…

Boson_Netsim_6使用方法
使用说明: netsim6.0只有在英文操作系统下才能释放出正确的pdf文件,大家可以到文档中心下载以下3个pdf文件: SequentialLabs.pdf:解压后复制到安装目录下的\MyLabs\ccna_sequential\Sequential Labs (CCNA)\common中覆盖相应的文件…

Ruby之Enumerator类
今天发现了Ruby1.8.6和 Ruby1.9.2的一个不同之处,试运行以下代码: require findputs Find.find("./data").class 在Ruby1.9.2中,最后的结果是Enumerator,而在Ruby1.8.6中,结果则是find: no block given (L…

澎思科技获IDG资本数千万元Pre-A轮融资 推出AI安防全场景软硬件解决方案
1月8日,人工智能安防公司澎思科技宣布完成数千万元 Pre-A 轮融资,该轮融资由 IDG 资本领投,高捷资本、上古资本、洪泰基金跟投。澎思科技表示,此轮融资会更多用来“修炼内功”,进一步夯实公司的技术研发和产品落地能力…

看linux书籍做的一些重要笔记(2011.07.03更新)
(1)制作启动盘 •用户可以用dd,cat,cp等命令自行将这些image文件制作成启动盘。 •例如: •ddif/mnt/cdrom/RedHat/images/bootdisk.img of/dev/fd0 •cp /mnt/cdrom/RedHat/images/bootdisk.img /dev/fd0 •cat /mnt…

C++ Primer 读书笔记 (1)
我的《C Primer》扉页记着购书的日期和地点:C Primer 2009.11.28购于西区求索。那时对于这本厚书一直心怀敬畏,仿佛是眼前的一座大山。那时,虽然已经大四,但是对于面向对象的理解还很肤浅(相当肤浅),只能用C编写一些简…

招聘:兼职ASP 高级工程师
工作职责:1、负责ASP网站设计和页面制作;2、配合运营团队做客户服务支持;3、参与海洋工作室其他相关设计工作。 职位描述: 1. 要求有很强大ASP开发功底;2. SQL Server使用经验;3. 有与策划者和美工合作的习惯;4. 可独立开发&…

GitHub重大好消息:私有仓库可无限制免费创建
作者 | 一一 出品 | AI科技大本营 GitHub 被微软收购之后,第一次公布了有利于广大程序员的好消息。 1 月 8 日,GitHub 宣布无限制的免费为普通用户提供私有仓库服务,这给程序员每年省下了 84 美元。此前,企业要创建私有仓库进行代…

“AI下乡”:华为和袁隆平一起种海水稻,欲改造1亿亩良田
作者| 琥珀 出品| AI科技大本营我们总是无法忘怀“杂交水稻之父”袁隆平的名字,即便后来很多学者对他的成就有所争议。距今,三系杂交水稻的发现已经过去了 50 多年,袁隆平也近 90 岁高龄,但他依然活跃在农业生产一线。想必近日不少…

finecms设置伪静态后分享到微信不能访问怎么处理
finecms设置伪静态后分享到微信不能访问,分享的链接自动增加了一串参数,类似这样的***.html?fromsinglemessage&isappinstalled0,刚开始ytkah没注意,以为是微信屏蔽了不安全网址,后面在论坛上问了一下,…

Access和SQL server开启表间关系,并实现更新或删除母表数据自动更新或删除子表数据...
1.Access开启表间关系,并实现删除母表数据自动删除子表数据: 在Tables等界面 - > 右键 - > Relationships... -> 弹出Relationships窗口 -> 选择需要关联的表 -> 双击Relationships窗口空白位置 -> 弹出 Edit Relationships 窗口 -> 就可以看到Enforce Re…

推荐并简要分析一个silverlight的相册DEMO--ImageSnipper(V2)
下面就是它的一些演示截图。 首先是缩放,旋转和透明处理:然后是文字水印处理:然后是使用Ink的涂鸭:相信做为一个相册(图片浏览)的基本功能已经没什么问题了。下面来看一下这个DEMO的类图ÿ…

Ruby之Tempfile
今天又机会尝试了下Ruby的Tempfile库,相比于自己创建临时文件再删除的方法简便了很多。 require tempfiletmp Tempfile.new("tmp")tmp.path # > /tmp/tmp20110928-12389-8yyc6w 不唯一tmp.write("This is a tempfile") tmp.rewind tmp.read…
快车 FlashGet 3.1 修正版(1057)
快车 FlashGet 3.1 修正版(1057) SM发布于 2009-06-25 23:43:23| 2326 次阅读 字体:大 小 打印预览感谢VxuE的投递快车(FlashGet)是互联网上最流行,使用人数最多的一款下载软件.采用多服务器超线程技术、全面支持多种协议,具有优秀的文件管理功能.快车是绿色软件,无…

Python模拟微博登陆,亲测有效!
作者 l 上海小胖 来源 l Python专栏(ID:xpchuiit)转载请联系授权(微信ID:pythonzhuanlan)今天想做一个微博爬个人页面的工具,满足一些不可告人的秘密。那么首先就要做那件必做之事!…

Ruby调用shell命令
原来发在diandian的几篇旧闻,也一并转到iteye上来吧。 1. exec exec echo "hello $HOSTNAME" 用echo命令来取代当前进程,无法知道命令是否成功 2. system system(echo "hello $HOSTNAME") 运行一个子shell来避免覆盖当前进程&a…