登录  | 加入社区

黑狼游客您好!登录后享受更多精彩

只需一步,快速开始

新浪微博登陆

只需一步, 快速开始

查看: 329|回复: 0

为什么你应该学 Python ?

[复制链接]

7

主题

0

帖子

0

现金

黑狼菜鸟

Rank: 1

积分
24
发表于 2017-12-5 18:00:00 | 显示全部楼层 |阅读模式 来自 美国
您的域名(hlsh.sh)未得到授权,部门功能受到影响!


尊重的用户:

  您好!非常感谢您能安装和关注本产物,为了产物的可连续发展和升级,众大云收罗已经开始收费。

  向用户收费是为了给用户更可靠的保障和服务,所收取的费用重要用于产物的正常运作、研发和改进,盼望各位可以或许明白和支持。

  别的,为了报答新老客户,众大云收罗3折优惠,原价980元,如今购买仅需290元,给您节流了690元。

  官方QQ群:23530791  客服QQ:155120699

  购买域名授权请打开下面的网址:

http://www.0762home.com/zt/csdn123_news/pay_url.php?url=hlsh.sh

  购买域名授权之后全部的未授权提示将主动消散,图片也正常表现,域名授权永世有用终身可用,后续的升级更新也是免费的,一次购买一辈子都能用,无后顾之忧!

提示:您现在利用的是免费试用版,可以手动删除上面的授权提示,发布这篇文章!


(点击上方蓝字,快速关注我们)



编译:伯乐在线 - 逆旅 
如有好文章投稿,请点击 → 这里相识详情


弁言


第一次打仗 Python 是在一节编程入门课上。实在,在此之前相识过它,以是在上课之前我对它的语法已经很认识了,但在上课之前我没有效它做过真正的项目。只管对它没有太大爱好,但我以为把它先容给人们去学习编程照旧很好的。我对它不是不喜好,而是一种“无所谓”的态度。缘故原由很简朴:它内里有太多“邪术”。 C 和 Java 这些语言,对底层的举动形貌的很清楚,Python 则完全相反。


别的,Python 布局疏松:写大型复杂步伐时,碰到规则严谨的步伐布局体(好比每个文件一个公共类),比其他语言(好比 Java )要费些力气。但是,在这些方面 Python 给了你很大的自由。


另一件事是严酷的编码风格和调试:由于Python 是表明型语言,查找题目不太轻易:假如C 语言有语法错误,编译器会直接制止编译,但在表明型语言中,直到实行到题目行,题目才会被发现。试着在必要整数的时间传一个字符串?cc 会立刻提示你,Python 表明器却对此一点都不介怀(固然有工具可以发现这个题目,好比 mypy,但我讨论的是通用的Python)。我提到的这些题目是表明型语言的通病,并非 Python 独有,但这些是我不喜好它的重要缘故原由。


另有一个烦人的题目是逼迫缩进。我们老师(很良好)以为这是功德情,由于“它逼迫我们形成简便的代码风格”。确实云云,但照旧有点烦,今世码没有按预期实行时,你分析代码想要找出 bug,它却无影无踪,过了很长时间之后你发现 if 语句那一行有一个多余的空格。


我曾经和同事聊过 Python,告诉他为什么我之前对这个语言不感冒,他笑着问我“问什么不喜好Python呢?由于它读起来很像英语?”。是的。由于这个语言做了许多底层的工作,有时间会不清晰发生了什么。举个读文件的例子,假设你想一行一行读取文件内容并打印出来。C 会这么做:


[color=#B85C00 !important]#include
 
[color=#800080 !important]int[color=#006FE0 !important] [color=teal !important]main[color=#333333 !important]([color=#800080 !important]void[color=#333333 !important])[color=#006FE0 !important] [color=#333333 !important]{
[color=#006FE0 !important]    [color=#002D7A !important]FILE[color=#006FE0 !important] *[color=#002D7A !important]fp[color=#333333 !important];
[color=#006FE0 !important]    [color=#800080 !important]char[color=#006FE0 !important] [color=#002D7A !important]buff[color=#333333 !important][[color=#009999 !important]256[color=#333333 !important]];[color=#006FE0 !important] [color=#999999 !important]// assuming a line won't contain more than 256 chars
[color=#006FE0 !important]    [color=#002D7A !important]fp[color=#006FE0 !important] = [color=teal !important]fopen[color=#333333 !important]([color=#DD1144 !important]"hello.txt"[color=#333333 !important],[color=#006FE0 !important] [color=#DD1144 !important]"r"[color=#333333 !important]);
 
[color=#006FE0 !important]    while[color=#333333 !important]([color=teal !important]fgets[color=#333333 !important]([color=#002D7A !important]buff[color=#333333 !important],[color=#006FE0 !important] [color=#009999 !important]256[color=#333333 !important],[color=#006FE0 !important] [color=#002D7A !important]fp[color=#333333 !important]))[color=#006FE0 !important] [color=#333333 !important]{
[color=#006FE0 !important]        printf[color=#333333 !important]([color=#DD1144 !important]"%s"[color=#333333 !important],[color=#006FE0 !important] [color=#002D7A !important]buff[color=#333333 !important]);
[color=#006FE0 !important]    [color=#333333 !important]}
 
[color=#006FE0 !important]    [color=teal !important]fclose[color=#333333 !important]([color=#002D7A !important]fp[color=#333333 !important]);
[color=#006FE0 !important]    return[color=#006FE0 !important] [color=#009999 !important]0[color=#333333 !important];
[color=#333333 !important]}


python 这么做:


with[color=#006FE0 !important] [color=teal !important]open[color=#333333 !important]([color=#DD1144 !important]'hello.txt'[color=#333333 !important])[color=#006FE0 !important] as[color=#006FE0 !important] [color=#002D7A !important]f[color=#006FE0 !important]:
[color=#006FE0 !important]    for[color=#006FE0 !important] [color=teal !important]line in[color=#006FE0 !important] [color=#002D7A !important]f[color=#006FE0 !important]:
[color=#006FE0 !important]        [color=teal !important]print[color=#333333 !important]([color=#002D7A !important]line[color=#333333 !important])


如今,许多人会以为这是 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 做雷同的事变:


[color=#002D7A !important]Get[color=#006FE0 !important]-ChildItem[color=#006FE0 !important] [color=#DD1144 !important]"."[color=#006FE0 !important] |
Foreach[color=#006FE0 !important]-[color=#800080 !important]Object[color=#006FE0 !important] [color=#333333 !important]{
[color=#006FE0 !important]    [color=#333333 !important]$[color=#002D7A !important]name[color=#006FE0 !important] = [color=#333333 !important]$[color=#002D7A !important]_[color=#333333 !important].[color=teal !important]Name
[color=teal !important]    [color=#002D7A !important]Write[color=#006FE0 !important]-Output[color=#006FE0 !important] [color=#DD1144 !important]"Processing $($name) file..."
[color=#333333 !important]}


An equivalent functionality in Python can be achieved with:


python 这么做:


[color=teal !important]from os import listdir
 
for[color=#006FE0 !important] f[color=#006FE0 !important] in[color=#006FE0 !important] [color=teal !important]listdir[color=#333333 !important]([color=#DD1144 !important]'.'[color=#333333 !important])[color=#006FE0 !important]:
[color=#006FE0 !important]    [color=teal !important]print[color=#333333 !important]([color=#DD1144 !important]'Processing {} file...'[color=#333333 !important].[color=teal !important]format[color=#333333 !important]([color=#002D7A !important]f[color=#333333 !important]))


如今我以为,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 ,内容如下:


[color=teal !important]cat
[color=teal !important]dog
[color=teal !important]mouse
[color=teal !important]bird
[color=teal !important]cat
[color=teal !important]cat
[color=#002D7A !important]dog


如今利用我们的脚本:


$> cat names.txt | namecount.py


Powershell:


$> Get-Content names.txt | python namecount.py


盼望的输出如下(次序大概会变革):


bird[color=#006FE0 !important] [color=#009999 !important]1
mouse[color=#006FE0 !important] [color=#009999 !important]1
cat[color=#006FE0 !important] [color=#009999 !important]3
dog[color=#006FE0 !important] [color=#009999 !important]2


namecount.py 源码:


[color=#B85C00 !important]#!/usr/bin/env python3
[color=teal !important]import sys
 
[color=teal !important]def count_names[color=#333333 !important]()[color=#006FE0 !important]:
[color=#006FE0 !important]    [color=#002D7A !important]names[color=#006FE0 !important] = [color=#333333 !important]{}
[color=#006FE0 !important]    for[color=#006FE0 !important] [color=teal !important]name in[color=#006FE0 !important] [color=#002D7A !important]sys[color=#333333 !important].[color=#002D7A !important]stdin[color=#333333 !important].[color=teal !important]readlines[color=#333333 !important]()[color=#006FE0 !important]:
[color=#006FE0 !important]        [color=#002D7A !important]name[color=#006FE0 !important] = [color=#002D7A !important]name[color=#333333 !important].[color=teal !important]strip[color=#333333 !important]()
 
[color=#006FE0 !important]        if[color=#006FE0 !important] [color=teal !important]name in[color=#006FE0 !important] [color=#002D7A !important]names[color=#006FE0 !important]:
[color=#006FE0 !important]            [color=#002D7A !important]names[color=#333333 !important][[color=#002D7A !important]name[color=#333333 !important]][color=#006FE0 !important] += [color=#009999 !important]1
[color=#006FE0 !important]        else[color=#006FE0 !important]:
[color=#006FE0 !important]            [color=#002D7A !important]names[color=#333333 !important][[color=#002D7A !important]name[color=#333333 !important]][color=#006FE0 !important] = [color=#009999 !important]1
[color=#006FE0 !important]            
[color=#006FE0 !important]    for[color=#006FE0 !important] [color=#002D7A !important]name[color=#333333 !important],[color=#006FE0 !important] [color=teal !important]count in[color=#006FE0 !important] [color=#002D7A !important]names[color=#333333 !important].[color=teal !important]items[color=#333333 !important]()[color=#006FE0 !important]:
[color=#006FE0 !important]        [color=#002D7A !important]sys[color=#333333 !important].[color=#002D7A !important]stdout[color=#333333 !important].[color=teal !important]write[color=#333333 !important]([color=#DD1144 !important]"{0}\t{1}\n"[color=#333333 !important].[color=teal !important]format[color=#333333 !important]([color=#002D7A !important]name[color=#333333 !important],[color=#006FE0 !important] [color=#002D7A !important]count[color=#333333 !important]))
 
if[color=#006FE0 !important] [color=#002D7A !important]__name__[color=#006FE0 !important] == [color=#DD1144 !important]"__main__"[color=#006FE0 !important]:
[color=#006FE0 !important]    [color=teal !important]count_names[color=#333333 !important]()


无序的信息可读性差,你大概想按单词出现的次数对其排序,让我们试试。我们要用管道输出文件内容供内建下令处置惩罚。按数字降序排序,我们要做的就是 $> cat names.txt | namecount.py | sort -rn 。假如利用PowerShell 应该如许:$> Get-Content names.txt | python namecount.py | Sort-Object { [int]$_.split()[-1] } -Descending (你大概听到了 Unixer 的吐槽声了,PowerShell 怎么这么繁琐)。


这回我们的输出是确定的,如下所示:


cat[color=#006FE0 !important] [color=#009999 !important]3
dog[color=#006FE0 !important] [color=#009999 !important]2
bird[color=#006FE0 !important] [color=#009999 !important]1
mouse[color=#006FE0 !important] [color=#009999 !important]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[color=#006FE0 !important] [color=teal !important]bs4 import[color=#006FE0 !important] [color=teal !important]BeautifulSoup
 
[color=#002D7A !important]soup[color=#006FE0 !important] = [color=teal !important]BeautifulSoup[color=#333333 !important]([color=#DD1144 !important]'Hello
'
[color=#333333 !important],[color=#006FE0 !important] [color=#DD1144 !important]'html.parser'[color=#333333 !important])
[color=#002D7A !important]soup[color=#333333 !important].[color=#002D7A !important]p


上面的代码使用第一个字符串参数创建了一个 BeautifulsSoup 实例,第二个参数表现我想利用 Python 自带的 HTML 剖析器(BeautifulSoup 可以搭配多种剖析器)。soup.p 返回一个 Tag(bs4.element.Tag) 对象,表现将作为第一个参数。


以上代码的输出是:


Hello



如今你大概会想,你说的邪术在哪?立刻就来。邪术在于上面的代码可以被修改为任何标签,乃至可以是自界说的。它意味着下面的代码也可以正常运行:


from[color=#006FE0 !important] [color=teal !important]bs4 import[color=#006FE0 !important] [color=teal !important]BeautifulSoup
[color=teal !important]
[color=#002D7A !important]soup[color=#006FE0 !important] = [color=teal !important]BeautifulSoup[color=#333333 !important]([color=#DD1144 !important]'Hello'[color=#333333 !important],[color=#006FE0 !important] [color=#DD1144 !important]'html.parser'[color=#333333 !important])
[color=#002D7A !important]soup[color=#333333 !important].[color=#002D7A !important]foobarfoo


The output is the following:


输出如下:


Hello


当我发现如许也能运行,我的反应是“怎么回事?”。由于,第一个例子很轻易实现,我的意思是最直接的方法是为每一个 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 雷同属性的内容的本领。下面是代码:


[color=#800080 !important]class[color=#006FE0 !important] [color=teal !important]Person[color=#333333 !important]([color=#800080 !important]object[color=#333333 !important])[color=#006FE0 !important]:
[color=#006FE0 !important]    [color=teal !important]def __init__[color=#333333 !important](self[color=#333333 !important],[color=#006FE0 !important] [color=#002D7A !important]first_name[color=#333333 !important])[color=#006FE0 !important]:
[color=#006FE0 !important]        self[color=#333333 !important].[color=#002D7A !important]first_name[color=#006FE0 !important] = [color=teal !important]first_name
 
[color=teal !important]    def __getattr__[color=#333333 !important](self[color=#333333 !important],[color=#006FE0 !important] [color=#002D7A !important]name[color=#333333 !important])[color=#006FE0 !important]:
[color=#006FE0 !important]        if[color=#006FE0 !important] [color=#333333 !important]([color=#002D7A !important]name[color=#006FE0 !important] == [color=#DD1144 !important]'name'[color=#333333 !important])[color=#006FE0 !important]:
[color=#006FE0 !important]            return[color=#006FE0 !important] self[color=#333333 !important].[color=teal !important]first_name
[color=teal !important]        raise AttributeError[color=#333333 !important]([color=#DD1144 !important]'Person object has no attribute \'{}\''[color=#333333 !important].[color=teal !important]format[color=#333333 !important]([color=#002D7A !important]name[color=#333333 !important]))


我们在终端运行代码:


[color=#002D7A !important]person[color=#006FE0 !important] = [color=teal !important]Person[color=#333333 !important]([color=#DD1144 !important]'Jason'[color=#333333 !important])
[color=#006FE0 !important]>>> [color=#002D7A !important]person[color=#333333 !important].[color=#002D7A !important]first[color=#333333 !important]_name
[color=#DD1144 !important]'Jason'
 
[color=#006FE0 !important]>>> [color=#002D7A !important]person[color=#333333 !important].name
[color=#DD1144 !important]'Jason'
 
[color=#006FE0 !important]>>> [color=#002D7A !important]person[color=#333333 !important].[color=teal !important]abc
[color=teal !important]Traceback[color=#006FE0 !important] [color=#333333 !important]([color=teal !important]most recent call [color=#002D7A !important]last[color=#333333 !important])[color=#006FE0 !important]:
[color=#006FE0 !important]  File[color=#006FE0 !important] [color=#DD1144 !important]""[color=#333333 !important],[color=#006FE0 !important] line[color=#006FE0 !important] [color=#009999 !important]1[color=#333333 !important],[color=#006FE0 !important] in[color=#006FE0 !important]
[color=#006FE0 !important]  File[color=#006FE0 !important] [color=#DD1144 !important]""[color=#333333 !important],[color=#006FE0 !important] line[color=#006FE0 !important] [color=#009999 !important]7[color=#333333 !important],[color=#006FE0 !important] in[color=#006FE0 !important] [color=teal !important]__getattr__
[color=#002D7A !important]AttributeError[color=#006FE0 !important]: [color=teal !important]Person [color=#800080 !important]object[color=#006FE0 !important] [color=teal !important]has no attribute[color=#006FE0 !important] [color=#DD1144 !important]'abc'


这意味着我们能凭空构造实例属性,是不是很棒?以是你可以偷偷的让你的 Dog 除了汪汪叫之外,还会喵喵叫:


[color=#800080 !important]class[color=#006FE0 !important] [color=teal !important]Dog[color=#333333 !important]([color=#800080 !important]object[color=#333333 !important])[color=#006FE0 !important]:
[color=#006FE0 !important]    [color=teal !important]def bark[color=#333333 !important](self[color=#333333 !important])[color=#006FE0 !important]:
[color=#006FE0 !important]        [color=teal !important]print[color=#333333 !important]([color=#DD1144 !important]'Ruff, ruff!'[color=#333333 !important])
[color=#006FE0 !important]    
[color=#006FE0 !important]    [color=teal !important]def __getattr__[color=#333333 !important](self[color=#333333 !important],[color=#006FE0 !important] [color=#002D7A !important]name[color=#333333 !important])[color=#006FE0 !important]:
[color=#006FE0 !important]        if[color=#333333 !important]([color=#002D7A !important]name[color=#006FE0 !important] == [color=#DD1144 !important]'meow'[color=#333333 !important])[color=#006FE0 !important]:
[color=#006FE0 !important]           return[color=#006FE0 !important] [color=#002D7A !important]lambda[color=#006FE0 !important]:  [color=teal !important]print[color=#333333 !important]([color=#DD1144 !important]'Meeeeeeow'[color=#333333 !important])
[color=#006FE0 !important]        [color=teal !important]raise AttributeError[color=#333333 !important]([color=#DD1144 !important]'I don\'t know what you\'re talking about...'[color=#333333 !important])


[color=#006FE0 !important]>>> [color=#002D7A !important]snoop[color=#006FE0 !important] = [color=teal !important]Dog[color=#333333 !important]()
 
[color=#006FE0 !important]>>> [color=#002D7A !important]snoop[color=#333333 !important].[color=teal !important]bark[color=#333333 !important]()
[color=#002D7A !important]Ruff[color=#333333 !important],[color=#006FE0 !important] [color=#002D7A !important]ruff[color=#006FE0 !important]!
 
[color=#006FE0 !important]>>> [color=#002D7A !important]snoop[color=#333333 !important].[color=teal !important]meow[color=#333333 !important]()
[color=#002D7A !important]Meeeeeeow


你可以在没有 reflection 的环境下,随意添加新属性。object.__dict__ 是(字典)[http://docs.python.org/3.5/library/stdtypes.html#typesmapping] 包罗 object 的属性和它们的值(留意我说的是 object.dict, object 是一个实例,另有一个 class.dict,是类的属性的字典)。


意思是:


[color=#800080 !important]class[color=#006FE0 !important] [color=teal !important]Dog[color=#333333 !important]([color=#800080 !important]object[color=#333333 !important])[color=#006FE0 !important]:
[color=#006FE0 !important]    
[color=#006FE0 !important]    [color=teal !important]def __init__[color=#333333 !important](self[color=#333333 !important])[color=#006FE0 !important]:
[color=#006FE0 !important]        self[color=#333333 !important].[color=#002D7A !important]name[color=#006FE0 !important] = [color=#DD1144 !important]'Doggy Dogg'


等价于:


[color=#800080 !important]class[color=#006FE0 !important] [color=teal !important]Dog[color=#333333 !important]([color=#800080 !important]object[color=#333333 !important])[color=#006FE0 !important]:
[color=#006FE0 !important]    
[color=#006FE0 !important]    [color=teal !important]def __init__[color=#333333 !important](self[color=#333333 !important])[color=#006FE0 !important]:
[color=#006FE0 !important]        self[color=#333333 !important].[color=#002D7A !important]__dict__[color=#333333 !important][[color=#DD1144 !important]'name'[color=#333333 !important]][color=#006FE0 !important] = [color=#DD1144 !important]'Doggy Dogg'


两者输出是一样的:


[color=#002D7A !important]snoop[color=#006FE0 !important] = [color=teal !important]Dog[color=#333333 !important]()
 
[color=#006FE0 !important]>>> [color=#002D7A !important]snoop[color=#333333 !important].name
[color=#DD1144 !important]'Doggy Dogg'


到这里你会想,是挺好的,但是有什么用呢?答案很简朴:magical APIs。你有没有效过一些 Python 库让你感觉像邪术?这是让它们变的有”邪术”的一种环境。固然一旦你懂了底层发生的事变,就会发现没有邪术。


假如你还想相识更多,可以检察文档中的 Description Protocol。


Python 的面向对象


Python 的面向对象有点希奇。比方,类中没有私有变量和方法。以是你想在类中创建一个实例变量或私有方法,你必须服从规则:



  • 一个下划线 (_)表现私有变量和方法。
  • 两个下划线(__) 表现的变量和方法,它们的名字会被修改。


举个例子,假设你有如下类:


[color=#800080 !important]class[color=#006FE0 !important] [color=teal !important]Foo[color=#333333 !important]([color=#800080 !important]object[color=#333333 !important])[color=#006FE0 !important]:
[color=#006FE0 !important]    [color=teal !important]def __init__[color=#333333 !important](self[color=#333333 !important])[color=#006FE0 !important]:
[color=#006FE0 !important]        self[color=#333333 !important].[color=#800080 !important]public[color=#006FE0 !important] = [color=#DD1144 !important]'public'
[color=#006FE0 !important]        self[color=#333333 !important].[color=#002D7A !important]_private[color=#006FE0 !important] = [color=#DD1144 !important]'public'
[color=#006FE0 !important]        self[color=#333333 !important].[color=#002D7A !important]__secret[color=#006FE0 !important] = [color=#DD1144 !important]'secret'


转到表明器:


[color=#006FE0 !important]>>> [color=#002D7A !important]foo[color=#006FE0 !important] = [color=teal !important]Foo[color=#333333 !important]()
[color=#006FE0 !important]>>> [color=#002D7A !important]foo[color=#333333 !important].[color=#800080 !important]public
[color=#DD1144 !important]'public'
[color=#006FE0 !important]>>> [color=#002D7A !important]foo[color=#333333 !important]._private
[color=#DD1144 !important]'public'
[color=#006FE0 !important]>>> [color=#002D7A !important]foo[color=#333333 !important].[color=teal !important]__secret
[color=teal !important]Traceback[color=#006FE0 !important] [color=#333333 !important]([color=teal !important]most recent call [color=#002D7A !important]last[color=#333333 !important])[color=#006FE0 !important]:
[color=#006FE0 !important]  File[color=#006FE0 !important] [color=#DD1144 !important]""[color=#333333 !important],[color=#006FE0 !important] line[color=#006FE0 !important] [color=#009999 !important]1[color=#333333 !important],[color=#006FE0 !important] in[color=#006FE0 !important]
[color=#002D7A !important]AttributeError[color=#006FE0 !important]: [color=#DD1144 !important]'Foo'[color=#006FE0 !important] [color=#800080 !important]object[color=#006FE0 !important] [color=teal !important]has no attribute[color=#006FE0 !important] [color=#DD1144 !important]'__secret'


如你所见,你可以访问 _private 变量,但是末了一个例子发生了什么,它是否意味着有两个下划线的变量是真正的私有变量?答案是 NO,它们的名字被改变了,现实上,它被 Python更换成了 _Foo_secret 。假如你想访问的话,你仍旧可以访问:


[color=#006FE0 !important]>>> [color=#002D7A !important]foo[color=#333333 !important].[color=#002D7A !important]_Foo_[color=#333333 !important]_secret
[color=#DD1144 !important]'secret'


然而,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》 ——比上面的主题要多,你会学到怎样写一个常见的用于实战的渗出测试,取证分析和安全脚本。


看完本文有劳绩?请转发分享给更多人

关注「Python开辟者」,提拔Python技能

za6ELNE7IyzZ6bjE.jpg




上一篇:选择一个 Python Web 框架:Django vs Flask vs Pyramid
下一篇:​Python​重要用来做什么 郑州那里有​Python​培训机构 ...
您需要登录后才可以回帖 登录 | 加入社区

本版积分规则

 

QQ|申请友链|小黑屋|手机版|Hlshell Inc. ( 豫ICP备16002110号-5 )

GMT+8, 2024-5-14 12:37 , Processed in 0.069532 second(s), 47 queries .

HLShell有权修改版权声明内容,如有任何爭議,HLShell將保留最終決定權!

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表