• 微博
  • 微信微信二维码

广东省人民政府首页  >  要闻动态  >  广东要闻

鸡巴大_

来源: 南方日报网络版     时间:2019-11-17 10:31:06

鸡巴大

引言第一次接触 Python 是在一节编程入门课上。其实,在此之前了解过它,所以在上课之前我对它的语法已经很

引言第一次接触 Python 是在一节编程入门课上

其实,在此之前了解过它,所以在上课之前我对它的语法已经很熟悉了,但在上课之前我没有用它做过真正的项目

尽管对它没有太大兴趣,但我认为把它介绍给人们去学习编程还是很好的

我对它不是不喜欢,而是一种“无所谓”的态度

原因很简单:它里面有太多“魔法”

C 和 Java 这些语言,对底层的行为描述的很清晰,Python 则完全相反

另外,Python 结构松散:写大型复杂程序时,遇到规则严谨的程序结构体(比如每个文件一个公共类),比其他语言(比如 Java )要费些力气

但是,在这些方面 Python 给了你很大的自由

另一件事是严格的编码风格和调试:因为Python 是解释型语言,查找问题不太容易:如果C 语言有语法错误,编译器会直接停止编译,但在解释型语言中,直到执行到问题行,问题才会被发现

试着在需要整数的时候传一个字符串?cc 会马上提醒你,Python 解释器却对此一点都不介意(虽然有工具可以发现这个问题,比如 mypy,但我讨论的是通用的Python)

我提到的这些问题是解释型语言的通病,并非 Python 独有,但这些是我不喜欢它的主要原因

还有一个烦人的问题是强制缩进

我们老师(很优秀)认为这是好事情,因为“它强制我们形成简洁的代码风格”

确实如此,但还是有点烦,当代码没有按预期执行时,你分析代码想要找出 bug,它却无影无踪,过了很长时间之后你发现 if 语句那一行有一个多余的空格

我曾经和同事聊过 Python,告诉他为什么我之前对这个语言不感冒,他笑着问我“问什么不喜欢Python呢?因为它读起来很像英语?”

是的

因为这个语言做了很多底层的工作,有时候会不清楚发生了什么

举个读文件的例子,假设你想一行一行读取文件内容并打印出来

C 会这么做:#include stdio int main(void) { FILE *fp; char buff[256]; // assuming a line wont contain more than 256 chars fp = fopen("hello.txt", "r"); while(fgets(buff, 256, fp)) { printf("%s", buff); } fclose(fp); return 0;}python 这么做:with open(hello.txt) as f: for line in f: print(line)现在,很多人会认为这是 python 的优势,然而,第一个例子中,干了什么一目了然:获取一个文件指针从文件读取每一行数据到缓存中,打印缓存中的内容关闭文件流python 的例子中看不到这些,它是一种 “魔法般的”过程

现在,有人认为这是好事,因为将程序员与底层实现细节隔离(我同意这个说法),但我想知道到底发生了什么

有趣的是,我以上提到的缺点,我现在认为都是优点

为了公平起见,我强调,Python 里边没有魔法,如果你多了解一点,你会发现真的没有,有的只是语言解释代码的方式,从这点来看,我发现它挺有意思的

如果你也这么觉得,我建议你深入了解它的工作机制,如果有东西像魔法,就找出来到底发生了什么,事情就会变得清晰,魔法就变成了便利

我的认识发生很大的变化,尤其是我决定使用 Python 后,事实上我现在是 Python 的死忠!现在你也许会想我将会在哪里说服你学 Python 是个好主意,不要担心,马上就到

作为引言的结尾,我想说明,这只是我对这个语言的个人感受,只是个人偏好

我没有试图以“如果你用 Python,你就不是真正的程序员(实际上,我不这么认为)”的理由劝说人们学 C

当有人问我他们的入门语言应该选哪个,我通常建议他们选 Python,基于我上边提到的“缺点”的原因

我的感觉来源于我的兴趣,我曾经在做一些很底层的东西,你能想到,Python 并不适用

Python 语言精粹在借用了JavaScript 畅销书 《JavaScript 语言精粹》作为本节标题后,我们开始讨论本文的主题:为什么你(没错,就是你!)应该学 Python

1、通用脚本语言这是我使用 Python 的主要原因

我曾经和很多人做过很多项目,不同的人用不同的系统

就我而言,我经常在windows系统和linux系统之间切换

举一个实际的例子,有一个项目,我写了项目的自动测试脚本,结果发现只有我能用,因为是用 PowerShell 写的,而我是项目中唯一使用 Windows 的

当时同事们自然认为 bash 是最好的,我还向他们解释 PowerShell 遵循一种不同的模式并且有它的强项(例如,它提供了 .NET 框架接口),它是面向对象的脚本语言,和 bash 完全不一样

现在我不想讨论哪个更好,因为这不是本文的重点

那么这个问题怎么解决呢?嗯…现在,是否有一种脚本语言可以在所有主流平台上运行呢?你猜对了,它就是 Python

除了可以在主流平台上运行,它还是开箱即用的脚本语言

标准库包含不少实用程序,提供了独立于系统的常用接口

举一个简洁明了的例子,假设你想获取文件夹下所有文件的文件名,然后对其进行处理,在 UNIX下,你要这么做:for f in *; do echo "Processing $f file..."; done用 PowerShell 做类似的事情:2018世界顶尖交易员量化投资巡讲·深圳站全球唯一的四次夺得“罗宾斯杯”世界交易锦标赛冠军的殿堂级大师意大利人安德烈·昂格尔来华首次工作坊式演讲零距离体验到一个真正获得业界高度认可的顶级程序化交易员的交易艺术2018年 1月20-21日 中国·深圳咨询电话/微信:18516600808Get-ChildItem "." |Foreach-Object { $name = $_.Name Write-Output "Processing $($name) file..."}An equivalent functionality in Python can be achieved with:python 这么做:from os import listdir for f in listdir(.): print(Processing {} file....format(f))现在我认为,Python 除了可以跑在 Linux,MacOSX 和 Windows 上,它也很易读

上边例子中的脚本很简单,在复杂的例子中不同语言的易读性差异会更明显

就像我之前提到的,Python 自带了许多强大的库用来取代 shell 脚本,你会发现,最有用的是:os – 提供系统无关功能,比如文件目录和文件读写

subprocess – 产生新进程、与输入输出流和返回代码交互

可以用它来启动系统已安装的程序,但请记住如果你担心脚本的可移植性,这不是最好的选择

shutil – 提供对文件和文件集合的高级操作

argparse – 解析命令行参数,构建命令行接口

好了,假设你 get 到了重点,跨平台和易读性听起来挺不错的,但是你真的喜欢类 UNIX shell 类似的语法怎么办?告诉你个好消息,鱼和熊掌可以兼得!看看 Plumbum,它是一个 Python 模块,它的座右铭是“ 再也不写 shell 脚本”

它模仿了 shell 语法,同时保持了跨平台

不要完全抛弃 shell 脚本即使 Python 可以完全取代 shell 脚本,但也不是必须这么做,因为 Python 脚本天生适合 Unix 命令行理念,你要做的就是让它们从 sys.stdin (标准输入)读数据,向 sys.stdout(标准输出)写数据

举个例子,假设你有一个文件,每行有一个单词,你想知道每个单词在文中出现的次数

这种情况就没必要全部是用Python,我们可以使用 cat 命令和我们的脚本,称它为 namecount.py 一起来完成这个任务

假设有一个文件,名为 names.txt ,内容如下:catdogmousebirdcatcatdog现在使用我们的脚本:$ cat names.txt | namecount.pyPowershell:$ Get-Content names.txt | python namecount.py期望的输出如下(顺序可能会变化):bird 1mouse 1cat 3dog 2namecount.py 源码:#!/usr/bin/env python3import sys def count_names(): names = {} for name in sys.stdin.readlines(): name = name.strip() if name in names: names[name] += 1 else: names[name] = 1 for name, count in names.items(): sys.stdout.write("{0}\t{1}\n".format(name, count)) if __name__ == "__main__": count_names()无序的信息可读性差,你可能想按单词出现的次数对其排序,让我们试试

我们要用管道输出文件内容供内建命令处理

按数字降序排序,我们要做的就是 $ cat names.txt | namecount.py | sort -rn

如果使用PowerShell 应该这样:$ Get-Content names.txt | python namecount.py | Sort-Object { [int]$_.split()[-1] } -Descending (你可能听到了 Unixer 的吐槽声了,PowerShell 怎么这么繁琐)

这回我们的输出是确定的,如下所示:cat 3dog 2bird 1mouse 1(旁注:如果你用 PowerShell,cat 是 Get-Content 的别名,sort 是 Sort_object 的别名,所以以上命令可以写成:$ cat names.txt | python namecount.py 和 $ cat names.txt | python namecount.py | sort { [int]$_.split()[-1] } -Descending )但愿我成功说服你 python 是你某些脚本的替代品,你不必完全抛弃 shell 脚本,因为你可以将 Python 融合到你现有的工作流和工具箱中,还可以从它跨平台,更好的可读性,还有丰富的库中获益(后面会讲)

2、大量优秀的库Python 有非常丰富的库

我的意思是,几乎任何事都有库(有趣的是:如果你在你的Python 解释器中输入 import antigravity,在浏览器中打开 xkdc 漫画的页面,是不是很酷?)

我不是很推崇堆叠模块式的编程,但你不必这样

因为有太多的库,不表示你都要使用

我也不喜欢堆叠模块(它有点像 CBSE),我在了解它们之后才使用

例如,我决定研究马尔科夫链,我想了一个项目:抓取一个艺术家的所有歌词,建立一个马尔科夫链,然后从其中生成歌曲

这个项目的目的是生成的歌曲应该能反映出艺术家的风格

所以我到处找相关的东西,搞出了 lyricst 项目(这只是个样品,还不成熟,只是一个测试项目,如我所言,我只是随便搞了一下,没想深入

如果你想玩的话,它包含有命令行界面和示例的说明文档)

我认为,最好的找歌词的地方是 RAPGenius,因为它很活跃,经常更新

为了获取艺术家所有的歌词,我必须从网站上爬,然后处理 HTML

幸运的是,Python 很适合做网络爬虫,它有强大的库像 BeautifulSoup 可以处理 HTML

所以我是这么做的,先使用 BeautifulSoup 从网页中抽取我需要的信息(就是歌词)然后用这些信息构建马尔科夫链

当然我曾经想用正则表达式构建自己的 HTML 解析器,但是这个库的存在让我更关注项目的最终目的:把玩马尔科夫链,让它更有趣,比方说,从文件中读取些内容出来

3、用来做渗透测试很强大如果你在作渗透测试或仅仅是喜欢玩玩,Python 是你的好帮手!由于Python 在所有 LInux 和 MAC OS 机器上都有安装,还有丰富的库,完善的语法,还是一门脚本语言,让它很适合干这个

另一个我为什么决定使用 Python 的原因(除了我之前提到的)是我对安全很感兴趣,Python 是用来做渗透测试的完美选择

我在第一次进入领域是通过 Scapy(或 Scapy3k ,python3),我印象很深

Scapy 能够创建、监听、解析数据包

它的 API 很简单,文档也很完善

你可以很容易的创建不同层的数据(我指的是 OSI 模型)或者捕获它们对其进行分析或修改

你甚至可以导出 pcap 文件用 Wireshark 打开

虽然除了抓包还能做很多事情,还有很多其他的库也可以,但我在这里不会涉及,因为这不是本文的重点而且要展开讲的话需要一篇文章

有人可能会说,“哦,太棒了,但我感兴趣的是 Windows 设备,里边不会自带 Python”

别当心,你可以用 py2exe 把你的脚本编译成 .exe 文件

文件可能会有点大(取决于你是用的库的数量),但这不是重点

如果你很好奇,请参考 list of Python pentesting tools

文末我还推荐了几本书

4、黑客的语言Python 是可塑性很强的语言

你可以用各种方法改造它

可参见《 altering the way imports work》和《messing with classes before they are created》这两篇文章

这只是一些例子

也让它成为强大的脚本语言(在第一节有说)适合做渗透测试(第三节),因为它给了你很大的自由

我不想讲太多,但我会讲述它让我惊讶的地方

当时,我在做一个网络爬虫( Python 很适合干这个!),我用的其中一个工具是 BeautifulSoup

这是我用来学习 Python 的项目之一

Beautifulsoup 处理 HTML 的语法清晰直观,原因是在自定义行为方面,Python 给了你很大的自由

了解一番 API 后,发现有 “魔法”

和这种情况类似:from bs4 import BeautifulSoup soup = BeautifulSoup(p class="someclass"Hello/p, html.parser)soup.p上面的代码利用第一个字符串参数创建了一个 BeautifulsSoup 实例,第二个参数表示我想使用 Python 自带的 HTML 解析器(BeautifulSoup 可以搭配多种解析器)

soup.p 返回一个 Tag(bs4.element.Tag) 对象,表示将作为第一个参数

以上代码的输出是:p class="someclass"Hello/p现在你可能会想,你说的魔法在哪?马上就来

魔法在于上面的代码可以被修改为任何标签,甚至可以是自定义的

它意味着下面的代码也可以正常运行:from bs4 import BeautifulSoupsoup = BeautifulSoup(foobarfoo class="someclass"Hello/foobarfoo, html.parser)soup.foobarfooThe output is the following:输出如下:foobarfoo class="someclass"Hello/foobarfoo当我发现这样也能运行,我的反应是“怎么回事?”

因为,第一个例子很容易实现,我的意思是最直接的方法是为每一个 HTML 标签定义一个属性(实例变量),在解析过程中如果找到了,就赋值给它们

但是这对第二种情况不适用,不可能对所有的字符串定义属性

我想知道它是怎么实现的,所以我打开 BeautifulSoups 源代码开始寻找

我没有发现任何命名为 p 的属性,这一点也不奇怪,解析函数没有对其赋值

谷歌一番后,我找到了答案:魔法方法

什么是魔法方法,为什么要叫这个名字?事实上,魔法方法是给你的类赋予魔法的方法

这种方法通常前后有两条下划线(例如 __init__()),在Python文档的 DataModel model section 有对它的说明

真正让 BeautifulSoup 拥有这个功能的魔法方法是__getattr__(self, name)(self 在python 中指向实例,和 Java 中的this 类似)

如果去查看文档,你会发现第一段如下:如果在属性常见地方找不到属性时,比如既不是实例属性,又没有在 self 类树中找到,则调用该方法(object.__getattr__(self, name))

参数 name 就是属性名这个方法应当返回(计算过的)属性值或抛出 AttributeError 异常

当你尝试访问一个不存在的属性,对象的 __getattr__(self,name) 方法会被调用,将返回一个以name 作为名字的属性的字符串

举个例子

假设你有一个 Person 类,拥有 first_name 属性

我们给使用者访问和 name 相同属性的内容的能力

下面是代码:class Person(object): def __init__(self, first_name): self.first_name = first_name def __getattr__(self, name): if (name == name): return self.first_name raise AttributeError(Person object has no attribute \{}\.format(name))我们在终端运行代码:person = Person(Jason) person.first_nameJason person.nameJason person.abcTraceback (most recent call last): File "stdin", line 1, in module File "stdin", line 7, in __getattr__AttributeError: Person object has no attribute abc这意味着我们能凭空构造实例属性,是不是很棒?所以你可以偷偷的让你的 Dog 除了汪汪叫之外,还会喵喵叫:class Dog(object): def bark(self): print(Ruff, ruff!) def __getattr__(self, name): if(name == meow): return lambda: print(Meeeeeeow) raise AttributeError(I don\t know what you\re talking about...) snoop = Dog() snoop.bark()Ruff, ruff! snoop.meow()Meeeeeeow你可以在没有 reflection 的情况下,随意添加新属性

object.__dict__ 是(字典)[https://docs.python.org/3.5/library/stdtypes.html#typesmapping] 包含 object 的属性和它们的值(注意我说的是 object.dict, object 是一个实例,还有一个 class.dict,是类的属性的字典)

意思是:class Dog(object): def __init__(self): self.name = Doggy Dogg等价于:class Dog(object): def __init__(self): self.__dict__[name] = Doggy Dogg两者输出是一样的:snoop = Dog() snoop.nameDoggy Dogg到这里你会想,是挺好的,但是有什么用呢?答案很简单:magical APIs

你有没有用过一些 Python 库让你感觉像魔法?这是让它们变的有”魔法”的一种情况

虽然一旦你懂了底层发生的事情,就会发现没有魔法

如果你还想了解更多,可以查看文档中的 Description Protocol

Python 的面向对象Python 的面向对象有点奇怪

例如,类中没有私有变量和方法

所以你想在类中创建一个实例变量或私有方法,你必须遵守规则:一个下划线 (_)表示私有变量和方法

两个下划线(__) 表示的变量和方法,它们的名字会被修改

举个例子,假设你有如下类:class Foo(object): def __init__(self): self.public = public self._private = public self.__secret = secret转到解释器: foo = Foo() foo.publicpublic foo._privatepublic foo.__secretTraceback (most recent call last): File "stdin", line 1, in moduleAttributeError: Foo object has no attribute __secret如你所见,你可以访问 _private 变量,但是最后一个例子发生了什么,它是否意味着有两个下划线的变量是真正的私有变量?答案是 NO,它们的名字被改变了,实际上,它被 Python替换成了 _Foo_secret

如果你想访问的话,你仍然可以访问: foo._Foo__secretsecret然而,PEP8 建议只在父类中使用双下划线来避免属性名冲突

“PEP”,表示 “Python Enhancement Proposal”,它用来描述 Python 特性或作用

如果你想要添加一个新特性,你可以创建一个 PEP,这样可以让整个社区可以看到并讨论

你可以在这里了解更多的 PEPs

可见,Python 很信任程序员

我不会再深入讲 OO 了,因为它需要单独一篇文章(甚至是一系列)来讲解

我确实想给你提个醒,Python 的 OO 可不像 Java 语言那么自然,你需要慢慢适应,但你知道吗,它只是做事的方法不同而已

举个例子,它没有抽象类,你必须使用装饰器来实现这个行为

结语希望这篇文章,能够给你一个学习 Python 的理由

这篇文章来自一个为过去说了Python 的坏话而愧疚,如今在到处宣传 Python 的人

我先申明一点,这只是个人喜好问题,当有人问我先学哪门语言时,我通常推荐 Python

如果你还没决定,那就给它一次机会!用上一两个小时,多读些关于它的东西

如果你喜欢从书上学习,我也会帮你,看看《Fluent Python》, 下节还有更多

书籍推荐我兑现了诺言,这一节推荐书籍

我会尽量保持简短一些,只包含一些我读过的书籍

《Fluent Python》 —— 一本讲 Python3 的好书

无论你是新手、熟手还是高手都值得一读

包含了 Python 的来龙去脉

《Web Scraping With Python》 —— 标题已经说明了一切,讲如何用Python 来做网络爬虫

你会探索如何爬网上的内容,解析 HTML 等

我觉得这本书对爬虫领域的新手和熟手很有帮助

即使你之前从没用过Python,你也可以看懂

它没有涉及任何高级主题

《Black Hat Python》 —— 这个有趣!你可以创建反弹 SSH shell,木马等等!如果你想知道 Python 如何做渗透测试,请一定要读它

注意它使用的是 Python 2,我有一个仓库,用的是 Python 3

《Violent Python: A Cookbook for Hackers, Forensic Analysts, Penetration Testers and Security Engineers》 ——比上面的主题要多,你会学到如何写一个常见的用于实战的渗透测试,取证分析和安全脚本

来源:伯乐在线 - 逆旅 盈利才是硬道理abc战法每日解盘视频直播(限时免费一周)李陈亮老师受电台邀请,在电台解盘视频直播一年,分析当前行情及指导未来操作方法

每周一到周五,晚上八点半到九点,学员可以与李老师互动答疑

【价格】:1580元立即联系下面的微信号,可以申请免费试看一周

电话/微信:18516600808




相关文章

版权所有:57fak 粤ICP备05070829 网站标识码4400000131
主办:南方新闻网 协办:广东省经济和信息化委员会 承办:南方新闻网
建议使用1024×768分辨率 IE7.0以上版本浏览器