Category Archive: Python

三月 31st, 2018

作为 Scribus 文档团队的长期成员,我要随时了解最新的源代码更新,以便对文档进行更新和补充。 我最近在刚升级到 Fedora 27 系统的计算机上使用 Subversion 进行检出操作时,对于下载该文档所需要的时间我感到很惊讶,文档由 HTML 页面和相关图像组成。 我恐怕该项目的文档看起来比项目本身大得多,并且怀疑其中的一些内容是“僵尸”文档——不再使用的 HTML 文件以及 HTML 中无法访问到的图像。

我决定为自己创建一个项目来解决这个问题。 一种方法是搜索未使用的现有图像文件。 如果我可以扫描所有 HTML 文件中的图像引用,然后将该列表与实际图像文件进行比较,那么我可能会看到不匹配的文件。

这是一个典型的图像标签:

  1. <img src="images/edit_shapes.png" ALT="Edit examples" ALIGN=left>

我对 src= 之后的第一组引号之间的部分很感兴趣。 在寻找了一些解决方案后,我找到一个名为 BeautifulSoup 的 Python 模块。 脚本的核心部分如下所示:

  1. soup = BeautifulSoup(all_text, 'html.parser')
  2. match = soup.findAll("img")
  3. if len(match) > 0:
  4. for m in match:
  5. imagelist.append(str(m))

我们可以使用这个 findAll 方法来挖出图片标签。 这是一小部分输出:

  1. <img src="images/pdf-form-ht3.png"/><img src="images/pdf-form-ht4.png"/><img src="images/pdf-form-ht5.png"/><img src="images/pdf-form-ht6.png"/><img align="middle" alt="GSview - Advanced Options Panel" src="images/gsadv1.png" title="GSview - Advanced Options Panel"/><img align="middle" alt="Scribus External Tools Preferences" src="images/gsadv2.png" title="Scribus External Tools Preferences"/>

到现在为止还挺好。我原以为下一步就可以搞定了,但是当我在脚本中尝试了一些字符串方法时,它返回了有关标记的错误而不是字符串的错误。 我将输出保存到一个文件中,并在 KWrite 中进行编辑。 KWrite 的一个好处是你可以使用正则表达式(regex)来做“查找和替换”操作,所以我可以用 \n<img 替换 <img,这样可以看得更清楚。 KWrite 的另一个好处是,如果你用正则表达式做了一个不明智的选择,你还可以撤消。

但我认为,肯定有比这更好的东西,所以我转而使用正则表达式,或者更具体地说 Python 的 re 模块。 这个新脚本的相关部分如下所示:

  1. match = re.findall(r'src="(.*)/>', all_text)
  2. if len(match)>0:
  3. for m in match:
  4. imagelist.append(m)

它的一小部分输出如下所示:

  1. images/cmcanvas.png" title="Context Menu for the document canvas" alt="Context Menu for the document canvas" /></td></tr></table><br images/eps-imp1.png" title="EPS preview in a file dialog" alt="EPS preview in a file dialog" images/eps-imp5.png" title="Colors imported from an EPS file" alt="Colors imported from an EPS file" images/eps-imp4.png" title="EPS font substitution" alt="EPS font substitution" images/eps-imp2.png" title="EPS import progress" alt="EPS import progress" images/eps-imp3.png" title="Bitmap conversion failure" alt="Bitmap conversion failure"

乍一看,它看起来与上面的输出类似,并且附带有去除图像的标签部分的好处,但是有令人费解的是还夹杂着表格标签和其他内容。 我认为这涉及到这个正则表达式 src="(.*)/>,这被称为贪婪,意味着它不一定停止在遇到 /> 的第一个实例。我应该补充一点,我也尝试过 src="(.*)",这真的没有什么更好的效果,我不是一个正则表达式专家(只是做了这个),找了各种方法来改进这一点但是并没什么用。

做了一系列的事情之后,甚至尝试了 Perl 的 HTML::Parser 模块,最终我试图将这与我为 Scribus 编写的一些脚本进行比较,这些脚本逐个字符的分析文本内容,然后采取一些行动。 为了最终目的,我终于想出了所有这些方法,并且完全不需要正则表达式或 HTML 解析器。 让我们回到展示的那个 img 标签的例子。

  1. <img src="images/edit_shapes.png" ALT="Edit examples" ALIGN=left>

我决定回到 src= 这一块。 一种方法是等待 s 出现,然后看下一个字符是否是 r,下一个是 c,下一个是否 =。 如果是这样,那就匹配上了! 那么两个双引号之间的内容就是我所需要的。 这种方法的问题在于需要连续识别上面这样的结构。 一种查看代表一行 HTML 文本的字符串的方法是:

  1. for c in all_text:

但是这个逻辑太乱了,以至于不能持续匹配到前面的 c,还有之前的字符,更之前的字符,更更之前的字符。

最后,我决定专注于 = 并使用索引方法,以便我可以轻松地引用字符串中的任何先前或将来的字符。 这里是搜索部分:

  1. index = 3
  2. while index < linelength:
  3. if (all_text[index] == '='):
  4. if (all_text[index-3] == 's') and (all_text[index-2] == 'r') and (all_text[index-1] == 'c'):
  5. imagefound(all_text, imagelist, index)
  6. index += 1
  7. else:
  8. index += 1
  9. else:
  10. index += 1

我用第四个字符开始搜索(索引从 0 开始),所以我在下面没有出现索引错误,并且实际上,在每一行的第四个字符之前不会有等号。 第一个测试是看字符串中是否出现了 =,如果没有,我们就会前进。 如果我们确实看到一个等号,那么我们会看前三个字符是否是 sr 和 c。 如果全都匹配了,就调用函数 imagefound

  1. def imagefound(all_text, imagelist, index):
  2. end = 0
  3. index += 2
  4. newimage = ''
  5. while end == 0:
  6. if (all_text[index] != '"'):
  7. newimage = newimage + all_text[index]
  8. index += 1
  9. else:
  10. newimage = newimage + '\n'
  11. imagelist.append(newimage)
  12. end = 1
  13. return

我们给函数发送当前索引,它代表着 =。 我们知道下一个字符将会是 ",所以我们跳过两个字符,并开始向名为 newimage 的控制字符串添加字符,直到我们发现下一个 ",此时我们完成了一次匹配。 我们将字符串加一个换行符(\n)添加到列表 imagelist 中并返回(return),请记住,在剩余的这个 HTML 字符串中可能会有更多图片标签,所以我们马上回到搜索循环中。

以下是我们的输出现在的样子:

  1. images/text-frame-link.png
  2. images/text-frame-unlink.png
  3. images/gimpoptions1.png
  4. images/gimpoptions3.png
  5. images/gimpoptions2.png
  6. images/fontpref3.png
  7. images/font-subst.png
  8. images/fontpref2.png
  9. images/fontpref1.png
  10. images/dtp-studio.png

啊,干净多了,而这只花费几秒钟的时间。 我本可以将索引前移 7 步来剪切 images/ 部分,但我更愿意把这个部分保存下来,以确保我没有剪切掉图像文件名的第一个字母,这很容易用 KWrite 编辑成功 —— 你甚至不需要正则表达式。 做完这些并保存文件后,下一步就是运行我编写的另一个脚本 sortlist.py

  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. # sortlist.py
  4. import os
  5. imagelist = []
  6. for line in open('/tmp/imagelist_parse4.txt').xreadlines():
  7. imagelist.append(line)
  8. imagelist.sort()
  9. outfile = open('/tmp/imagelist_parse4_sorted.txt', 'w')
  10. outfile.writelines(imagelist)
  11. outfile.close()

这会读取文件内容,并存储为列表,对其排序,然后另存为另一个文件。 之后,我可以做到以下几点:

  1. ls /home/gregp/development/Scribus15x/doc/en/images/*.png > '/tmp/actual_images.txt'

然后我需要在该文件上运行 sortlist.py,因为 ls 方法的排序与 Python 不同。 我原本可以在这些文件上运行比较脚本,但我更愿意以可视方式进行操作。 最后,我成功找到了 42 个图像,这些图像没有来自文档的 HTML 引用。

这是我的完整解析脚本:

  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. # parseimg4.py
  4. import os
  5. def imagefound(all_text, imagelist, index):
  6. end = 0
  7. index += 2
  8. newimage = ''
  9. while end == 0:
  10. if (all_text[index] != '"'):
  11. newimage = newimage + all_text[index]
  12. index += 1
  13. else:
  14. newimage = newimage + '\n'
  15. imagelist.append(newimage)
  16. end = 1
  17. return
  18. htmlnames = []
  19. imagelist = []
  20. tempstring = ''
  21. filenames = os.listdir('/home/gregp/development/Scribus15x/doc/en/')
  22. for name in filenames:
  23. if name.endswith('.html'):
  24. htmlnames.append(name)
  25. #print htmlnames
  26. for htmlfile in htmlnames:
  27. all_text = open('/home/gregp/development/Scribus15x/doc/en/' + htmlfile).read()
  28. linelength = len(all_text)
  29. index = 3
  30. while index < linelength:
  31. if (all_text[index] == '='):
  32. if (all_text[index-3] == 's') and (all_text[index-2] == 'r') and
  33. (all_text[index-1] == 'c'):
  34. imagefound(all_text, imagelist, index)
  35. index += 1
  36. else:
  37. index += 1
  38. else:
  39. index += 1
  40. outfile = open('/tmp/imagelist_parse4.txt', 'w')
  41. outfile.writelines(imagelist)
  42. outfile.close()
  43. imageno = len(imagelist)
  44. print str(imageno) + " images were found and saved"

脚本名称为 parseimg4.py,这并不能真实反映我陆续编写的脚本数量(包括微调的和大改的以及丢弃并重新开始写的)。 请注意,我已经对这些目录和文件名进行了硬编码,但是很容易变得通用化,让用户输入这些信息。 同样,因为它们是工作脚本,所以我将输出发送到 /tmp 目录,所以一旦重新启动系统,它们就会消失。

这不是故事的结尾,因为下一个问题是:僵尸 HTML 文件怎么办? 任何未使用的文件都可能会引用图像,不能被前面的方法所找出。 我们有一个 menu.xml 文件作为联机手册的目录,但我还需要考虑 TOC(LCTT 译注:TOC 是 table of contents 的缩写)中列出的某些文件可能引用了不在 TOC 中的文件,是的,我确实找到了一些这样的文件。

最后我可以说,这是一个比图像搜索更简单的任务,而且开发的过程对我有很大的帮助。

 

三月 27th, 2018
这篇文章主要为大家详细介绍了Python入门必须知道的11个知识点,帮助更好地了解python,感兴趣的小伙伴们可以参考一下

Python被誉为全世界高效的编程语言,同时也被称作是“胶水语言”,那它为何能如此受欢迎,下面我们就来说说Python入门学习的必备11个知识点,也就是它为何能够如此受欢迎的原因.

Python 简介

Python 是一个高层次的结合了解释性、编译性、互动性和面向对象的脚本语言。

Python 的设计具有很强的可读性,相比其他语言经常使用英文关键字,其他语言的一些标点符号,它具有比其他语言更有特色语法结构。

Python 是一种解释型语言: 这意味着开发过程中没有了编译这个环节。类似于PHP和Perl语言。

Python 是交互式语言: 这意味着,您可以在一个Python提示符,直接互动执行写你的程序。

Python 是面向对象语言: 这意味着Python支持面向对象的风格或代码封装在对象的编程技术。

Python 是初学者的语言:Python 对初级程序员而言,是一种伟大的语言,它支持广泛的应用程序开发,从简单的文字处理到 WWW 浏览器再到游戏。

Python 发展历史

Python 是由 Guido van Rossum 在八十年代末和九十年代初,在荷兰国家数学和计算机科学研究所设计出来的。
Python 本身也是由诸多其他语言发展而来的,这包括 ABC、Modula-3、C、C++、Algol-68、SmallTalk、Unix shell 和其他的脚本语言等等。
像 Perl 语言一样,Python 源代码同样遵循 GPL(GNU General Public License)协议。
现在 Python 是由一个核心开发团队在维护,Guido van Rossum 仍然占据着至关重要的作用,指导其进展。

Python 特点

1.易于学习:Python有相对较少的关键字,结构简单,和一个明确定义的语法,学习起来更加简单。

2.易于阅读:Python代码定义的更清晰。

3.易于维护:Python的成功在于它的源代码是相当容易维护的。

4.一个广泛的标准库:Python的最大的优势之一是丰富的库,跨平台的,在UNIX,Windows和Macintosh兼容很好。

5.互动模式:互动模式的支持,您可以从终端输入执行代码并获得结果的语言,互动的测试和调试代码片断。

6.可移植:基于其开放源代码的特性,Python已经被移植(也就是使其工作)到许多平台。

7.可扩展:如果你需要一段运行很快的关键代码,或者是想要编写一些不愿开放的算法,你可以使用C或C++完成那部分程序,然后从你的Python程序中调用。

8.数据库:Python提供所有主要的商业数据库的接口。

9.GUI编程:Python支持GUI可以创建和移植到许多系统调用。

10.可嵌入: 你可以将Python嵌入到C/C++程序,让你的程序的用户获得”脚本化”的能力。

1、Python适用于哪些应用场景?

这个没有固定答案,很多人都说Python不适合开发GUI的程序,但Python自己的IDE——IDEL和第三方的IDE——Eric就是Python写的。

目前看到的更多的人是拿来写Web,使用如Django、web.py框架,没记错Flask也是。
也有一个情况用的比较多,用Python当胶水,与各种语言结合,共同完成某软件功能,注意观察也许你会发现在安装一些软件的时候会有Python的身影。

我个人还拿Python模拟过端口转发和DNS服务等,所以真的是要看真么用,而不是能怎么用。

另外大数据分析Python也是比较适合的,从载入到分析,再到保存结果等,Python有一整套的模块应对。

2、Python能够胜任大数据吗?

Python很适合做大数据相关的分析,内置的C编译的模块能应对常见的操作,个别极端的算法建议用C重写相关模块。

Python本身的特点更多的是高效率的开发和简单的维护,速度交给C去吧,更多的问题其实出自写代码的人没有更好的使用,而不是效率不够高。比如排序,本来Python有非常高效的内置C编译的模块,却非要自己写算法,这样的结果不慢都是奇怪的。

另外还要看需求是CPU密集型,还是IO密集型,如果是CPU密集型建议这部分操作由C实现,IO密集型的效率不会因为Python而有多少改变。

C的效率是高,但框架搭起来也费劲,所以还是结合着来吧,也因此,Python被称为胶水语言。

3、Python是否可以完全代替Shell?

完全可以,Shell的功能Python均可实现,而且代码量更少、结构更优、可阅读性更好,而Python可实现的功能Shell却不一定能,如运维中会用到的用于网络通信的Socket模块、用于WEB的Django框架、用于性能采集的psutil模块等,而且Shell对操作系统的命令依赖性较强,Python可在更大程度上规避。

在一个Shell的IDE是个很大的问题,虽然Python的原生IDE不怎么样,但第三方的IDE还是功能十分强大的,虽然不能和微软的Virtual Studio相媲美,但也是能完全满足Python的开发需求的。

再说下Python的效率问题,Python支持多进程、多线程以及协程(比线程更小一级),程序并发度是在Shell之上的。Python的核心模块基本都是用C实现的,因此效率更高。如有必要也可能将需要用Python实现的Python模块用C重写以提高效率,当然也可以直接用C Python,一个直接完全用C实现的Python解释器。

4、Python是否可以访问常见的数据库?

可以,Python可以访问常见的各种数据库,如Oracle、MySQL、Vertica、SQLServer等,加载相应的模块即可,模块列表如下:
Oracle:cx_Oracle
MySQL:MySQLdb

5、Python开发是面向过程、函数还是对象?

Python虽然是解释型语言,但从设计之初就已经是一门面向对象的语言,对于Python来说一切皆为对象。正因为如此,在Python中创建一个类和对象是很容易的,当然如果习惯面向过程或者函数的写法也是可以的,Python并不做硬性的限制。

Python的面向对象特征如下:

封装

面向对象程序设计中的术语对象(Object)基本上可以看做数据(特性)以及由一系列可以存取、操作这些数据的方法所组成的集合。传统意义上的“程序= 数据结构+算法”被封装”掩盖“并简化为“程序=对象+消息”。对象是类的实例,类的抽象则需要经过封装。封装可以让调用者不用关心对象是如何构建的而直接进行使用。

继承

类继承:

继承给人的直接感觉是这是一种复用代码的行为。继承可以理解为它是以普通的类为基础建立专门的类对象,子类和它继承的父类是IS-A的关系。

多重继承:

不同于C#,Python是支持多重类继承的(C#可继承自多个Interface,但最多继承自一个类)。多重继承机制有时很好用,但是它容易让事情变得复杂。

多态

多态意味着可以对不同的对象使用同样的操作,但它们可能会以多种形态呈现出结果。在Python中,任何不知道对象到底是什么类型,但又需要对象做点什么的时候,都会用到多态。方法是多态的,运算符也是多态的。

6、如何快速掌握Python?

阅读官方文档即可满足日常需求,官方文档有中文翻译,更加方便学习。但这些都是基础的语法和常见的模块,Python学习重要的是模块,快速、高效的开发依赖的是模块的应用,站在前人的肩膀会省时省力的多。

但学习Python其实最重要的是学习模块,而非语法本身,Python的语法十分简单,只要大学学过C或者数据结构课程,甚至完全没学过的人也是可以轻松掌握的。掌握了语法已经可以实现Shell的功能,但要想提高模块的学习必不可少,如运维人员经常用的有:

psutil:获取性能信息

socket:基本网络通信

IPy:IP地址相关处理

dnsptyhon:域名相关处理

difflib:文件比较

pexpect:屏幕信息获取,常用于自动化

paramiko:SSH客户端

XlsxWriter:Excel相关处理

其他还有很多很多功能模块,每天也不断的有新的模块、框架、组件产生,如用于与Java 做桥接的PythonJS,甚至Python还可以编写Map和Reduce。

7、Python是否有专用的IDE工具?

有,IDEL用Python实现的Python的IDE工具,但说实话,功能真心不咋地。我个人常用的IDE如下:

PyCharm

PyCharm是JetBrains开发的Python IDE。PyCharm用于一般IDE具备的功能,比如,调试、语法高亮、Project管理、代码跳转、智能提示、自动完成、单元测试、版本控制……另外,PyCharm还提供了一些很好的功能用于Django开发,同时支持Google App Engine,更酷的是,PyCharm支持IronPython!

Wing IDE

Wingware的Python IDE兼容Python 2.x和3.x,可以结合Django,matplotlib,Zope, Plone,App Engine,PyQt,PySide,wxPython,PyGTK,Tkinter,mod_wsgi,pygame,Maya,MotionBuilder,NUKE,Blender和其他Python框架使用。Wing支持测试驱动开发,集成了单元测试,nose和Django框架的执行和调试功能。Wing IDE启动和运行的速度都非常快,支持Windows,Linux,OS X和Python versi。

NotePad++

简单、方便,但仅适合临时性的更改。

其他的还有:Eclipse withPyDev、Sublime Text、Komodo Edit、Pyer、The Eric Python IDE、Interactive Editor for Python

8、运用Python实现系统自动化监控有哪些常用方法?

准确的说应该是有哪些模块,健康监控肯定要有psutil来监控性能,还会用到通信的Socket,登陆的Paramiko、telnetlib,ftp的ftplib。

原理基本就是采集数据——本地处理数据——传输数据,如果做的比较完善可以再做个呈现数据,也可以吧数据发送给Zabbix等开源工具。

个人还用一个开源监控网络刺探的,超过指定次数就自动封杀。

9、Python可运行在那些平台?跨平台性如何?

支持常见的主流平台,如AIX、HPUX、Solaris、Linux、Windows等,除Windows外常见的Unix、Linux平台均带有原生的Python,但版本一般较低。关于跨平台和他跨平台语言一样,要注意有些个别模块是单一平台特有的,整体的跨平台性还是很好的,不必为适应多平台写多套代码。

但这不是说一点限制都没有:首先,同一个版本的中间文件.py和.pyc以及.pyo是跨平台的;其次,PC与移动终端,如:手机、Pad不可跨平台(原因见下一条);最后,不能跨处理器构架,如:Intel与ARM,64位与32位。

10、如何利用Python提高开发效率?

因为Python很多底层的东西不用自己写,模块资源丰富,运用得当开发效率当然会提升,而且各种框架也为快速开发提供了基础。

11、Python运行速度如何?

通常Java的速度比Python快些。Python调用C扩展除外(也可以直接用CPython)。
对于Python速度太慢的批评,Python语言作者Guido van Rossum说:

如果你开发的系统发现了性能瓶颈,通常最有效率的做法是找到出问题的代码块,用速度较快的语言如C或C++写一些代码替换该功能或该模块,而不是用C或C++重写整个系统,因为对大部分代码而言,语言的速度是无关紧要的。

学习是一个人最大的修养,通过学习不仅可以提升自己的境界,还能丰富知识,为以后的就业打下基础,学习Python更是一个发展自己的好机会,毕竟人工智能时代已经到来,Python作为人工智能时代的主力军是非常有前景的,梦想没有腐朽,一路还有汗流。加油!

三月 27th, 2018
这篇文章主要介绍了Python中列表(List)的详解操作方法,包含创建、访问、更新、删除、其它操作等,需要的朋友可以参考下

列表是Python中最基本的数据结构,列表是最常用的Python数据类型,列表的数据项不需要具有相同的类型。列表中的每个元素都分配一个数字 – 它的位置,或索引,第一个索引是0,第二个索引是1,依此类推。
Python有6个序列的内置类型,但最常见的是列表和元组。序列都可以进行的操作包括索引,切片,加,乘,检查成员。此外,Python已经内置确定序列的长度以及确定最大和最小的元素的方法。

一、创建一个列表
只要把逗号分隔的不同的数据项使用方括号括起来即可。如下所示:

复制代码代码如下:
list1 = [‘physics’, ‘chemistry’, 1997, 2000];
list2 = [1, 2, 3, 4, 5 ];
list3 = [“a”, “b”, “c”, “d”];

与字符串的索引一样,列表索引从0开始。列表可以进行截取、组合等。
二、访问列表中的值
使用下标索引来访问列表中的值,同样你也可以使用方括号的形式截取字符,如下所示:

复制代码代码如下:
#!/usr/bin/python

list1 = [‘physics’, ‘chemistry’, 1997, 2000];
list2 = [1, 2, 3, 4, 5, 6, 7 ];print “list1[0]: “, list1[0]
print “list2[1:5]: “, list2[1:5]

以上实例输出结果:

复制代码代码如下:
list1[0]:  physics
list2[1:5]:  [2, 3, 4, 5]

三、更新列表
你可以对列表的数据项进行修改或更新,你也可以使用append()方法来添加列表项,如下所示:

复制代码代码如下:
#!/usr/bin/pythonlist = [‘physics’, ‘chemistry’, 1997, 2000];

print “Value available at index 2 : ”
print list[2];
list[2] = 2001;
print “New value available at index 2 : ”
print list[2];

以上实例输出结果:

复制代码代码如下:
Value available at index 2 :
1997
New value available at index 2 :
2001

四、删除列表元素
可以使用 del 语句来删除列表的的元素,如下实例:

复制代码代码如下:
#!/usr/bin/pythonlist1 = [‘physics’, ‘chemistry’, 1997, 2000];

print list1;
del list1[2];
print “After deleting value at index 2 : ”
print list1;

以上实例输出结果:

复制代码代码如下:
[‘physics’, ‘chemistry’, 1997, 2000]
After deleting value at index 2 :
[‘physics’, ‘chemistry’, 2000]

五、Python列表脚本操作符
列表对 + 和 * 的操作符与字符串相似。+ 号用于组合列表,* 号用于重复列表。如下所示:

Python 表达式 结果 描述
len([1, 2, 3]) 3 长度
[1, 2, 3] + [4, 5, 6] [1, 2, 3, 4, 5, 6] 组合
[‘Hi!’] * 4 [‘Hi!’, ‘Hi!’, ‘Hi!’, ‘Hi!’] 重复
3 in [1, 2, 3] True 元素是否存在于列表中
for x in [1, 2, 3]: print x, 1 2 3 迭代

六、Python列表截取
Python的列表截取与字符串操作类型,如下所示:

复制代码代码如下:
L = [‘spam’, ‘Spam’, ‘SPAM!’]

操作:

Python 表达式 结果 描述
L[2] ‘SPAM!’ 读取列表中第三个元素
L[-2] ‘Spam’ 读取列表中倒数第二个元素
L[1:] [‘Spam’, ‘SPAM!’] 从第二个元素开始截取列表

七、Python列表操作的函数和方法
列表操作包含以下函数:
1、cmp(list1, list2):比较两个列表的元素
2、len(list):列表元素个数
3、max(list):返回列表元素最大值
4、min(list):返回列表元素最小值
5、list(seq):将元组转换为列表
列表操作包含以下方法:
1、list.append(obj):在列表末尾添加新的对象
2、list.count(obj):统计某个元素在列表中出现的次数
3、list.extend(seq):在列表末尾一次性追加另一个序列中的多个值(用新列表扩展原来的列表)
4、list.index(obj):从列表中找出某个值第一个匹配项的索引位置
5、list.insert(index, obj):将对象插入列表
6、list.pop(obj=list[-1]):移除列表中的一个元素(默认最后一个元素),并且返回该元素的值
7、list.remove(obj):移除列表中某个值的第一个匹配项
8、list.reverse():反向列表中元素
9、list.sort([func]):对原列表进行排序

三月 1st, 2018

Python3发布以来,获取了广大程序员们的差评,说不稳定,又是不兼容什么的,不过差评归差评,Python3既然已经发布,肯定是个趋势,但在Python3.4里面,使用原来Python2.7的MySQLdb已经不能连接MySQL数据库了,比较令人纠结,不过我们可以使用PyMySQL,来完成连接MySQL的重任,步骤如下:

序号 描述
1 去github上下载pymysql的安装包 pymysql
2 解压到某个盘符下
3 打开cmd窗口(win环境下),进入pymysql的根目录下执行命令,python setup.py install
4 在程序里,导入pymysql
5 开始连接数据库

数据库操作的API文档连接: http://legacy.python.org/dev/peps/pep-0249/

代码如下:

__author__ = 'qindongliang'
#导入pymysql的包
import pymysql
try:
#获取一个数据库连接,注意如果是UTF-8类型的,需要制定数据库
conn=pymysql.connect(host='localhost',user='root',passwd='qin',db='person',port=3306,charset='utf8')
cur=conn.cursor()#获取一个游标
cur.execute('select * from person')
data=cur.fetchall()
for d in data :
#注意int类型需要使用str函数转义
 print("ID: "+str(d[0])+'  名字: '+d[1]+"  性别: "+d[2])

cur.close()#关闭游标
conn.close()#释放数据库资源
except  Exception :print("发生异常")

结果如下:

D:\python\python.exe D:/pythonide/pythonprojectworkspace/python/mysql.py
ID: 1  名字: 秦天  性别: 男
ID: 2  名字: 王晶  性别: 女

Process finished with exit code 0
TAGS:
一月 30th, 2018

Ubuntu 将Python从默认的2.7升级到3.* 版本(建议使用原系统Python版本进行Python开发)

因为Ubuntu很多底层采用的是Python2.*,Python3和Python2是互相不兼容的,所以此时不能卸载Python2,需要将默认Python的指向Python3。

先刷新源 sudo apt-get update

然后更新系统 sudo apt-get dist-upgrade就行了

在ubuntu 的终端中用代码下载最新的Python

sudo apt-get install python3

刚才下载的Python程序被安装在usr/local/lib/python3.5 中

cd /usr/local/lib

ls -l

pwd

root@linuxidc.com:~# cd /usr/local/lib
root@linuxidc.com:/usr/local/lib# ls -l
总用量 8
drwxrwsr-x 4 root staff 4096 12月 27 19:55 python2.7
drwxrwsr-x 3 root staff 4096 4月  12  2017 python3.5
root@linuxidc.com:/usr/local/lib# pwd
/usr/local/lib
root@linuxidc.com:/usr/local/lib#

我们先备份 sudo cp /usr/bin/python /usr/bin/python_bak

然后用命令删除usr/bin/目录下的默认python link文件

run24pro@linuxidc.com:/usr/local/lib$ cd /usr/local/lib
run24pro@linuxidc.com:/usr/local/lib$ cd /usr/bin/
run24pro@linuxidc.com:/usr/bin$ sudo cp /usr/bin/python /usr/bin/python_bak
run24pro@linuxidc.com:/usr/bin$ rm -rf python
rm: 无法删除’python’: 权限不够
run24pro@linuxidc.com:/usr/bin$ sudo -i
root@linuxidc.com:~# rm -rf python
root@linuxidc.com:~#

给系统默认python编译器建立新的连接

ln -s /usr/bin/python3.5 /usr/bin/python 注:如果要换回python2.7 先删除link然后这样 ln -s /usr/bin/python2.7 /usr/bin/python

run24pro@linuxidc.com:/usr/bin$ sudo -i
root@linuxidc.com:~# rm -rf python
root@linuxidc.com:~# cd /usr/bin/
root@linuxidc.com:/usr/bin# ln -s /usr/bin/python3.5 /usr/bin/python
ln: 无法创建符号链接’/usr/bin/python’: 文件已存在
root@linuxidc.com:/usr/bin# ln -s /usr/bin/python3.5 /usr/bin/python
ln: 无法创建符号链接’/usr/bin/python’: 文件已存在
root@linuxidc.com:/usr/bin# python
Python 2.7.13 (default, Nov 23 2017, 15:37:09)
[GCC 6.3.0 20170406] on linux2
Type “help”, “copyright”, “credits” or “license” for more information.
>>> quit()
root@linuxidc.com:/usr/bin# rm -rf python
root@linuxidc.com:/usr/bin# ln -s /usr/bin/python3.5 /usr/bin/python
root@linuxidc.com:/usr/bin# python
Python 3.5.3 (default, Nov 23 2017, 11:34:05)
[GCC 6.3.0 20170406] on linux
Type “help”, “copyright”, “credits” or “license” for more information.

输入 python

root@linuxidc.com:/usr/bin# python
Python 3.5.3 (default, Nov 23 2017, 11:34:05)
[GCC 6.3.0 20170406] on linux
Type “help”, “copyright”, “credits” or “license” for more information.
>>>

成功!

如果遇到其它问题,需要修复的话,重新下载一下就好。

sudo apt-get install –reinstall python-minimal
sudo apt-get install –reinstall python2.7

注:

如果用的是python3.5,但如果修复后,之前下的pip,django,还有其它都是在python3对应的情况下下的,会出一些问题。因为不兼容。

这样的话,建议还是重装系统,然后使用python2.7,不要升级,以后就安装相对应的版本软件。这样就不会出现不兼容的问题。

TAGS:
十二月 31st, 2017

CentOS 7 默认的python版本是python2.7.5。因为yum依赖于默认的python版本的缘由,所以要先保留默认版本,并修改yum文件头部后,才能开始安装更新python2和python3两个最新版本。(python2和python3共存)

一. 保留默认python版本2.7.5,并修改yum头部,保持yum对默认版本python2.7.5的依赖

1.su root  # 获取root权限

2.mv /usr/bin/python2.7 /usr/bin/python2.7.5  # 保留默认版本python为python2.7.5

ln -s /usr/bin/python2.7.5 /usr/local/bin/python2.7.5  # 创建软连接
3.ll /usr/bin/yum*  # 查看/usr/bin/目录下所有yum文件(7个)头部

4.vi /usr/bin/yum*  # 修改/usr/bin/目录下所有yum文件(7个)头部

#!/usr/bin/python —> #!/usr/bin/python2.7.5

5.vi /usr/libexec/urlgrabber-ext-down  # 修改/usr/libexec/目录下 urlgrabber-ext-down头部

#!/usr/bin/python —> #!/usr/bin/python2.7.5

二. 安装最新版python2.7.13和python3.6.2(python2和python3共存,修改后默认版本为python3.6.2)

准备工作:

1. 安装wget命令(可以在线下载安装包的命令)

yum -y install wget

2. 准备编译环境

yum groupinstall ‘Development Tools’
yum install zlib-devel bzip2-devel openssl-devel ncurses-devel
3. 下载并安装最新版本的python2和python3的tgz压缩文件

https://www.python.org/ftp/python/2.7.13/Python-2.7.13.tgz
https://www.python.org/ftp/python/3.6.2/Python-3.6.2.tgz

开始安装:

1. 进入下载目录:

cd /usr/local/src

2. 下载并安装最新版本python2:
wget https://www.python.org/ftp/python/2.7.13/Python-2.7.13.tgz
tar zxvf Python-2.7.13.tgz
cd Python-2.7.13
./configure
make all
make install
make clean
make distclean
rm -rf /usr/bin/python
rm -rf /usr/bin/python2
rm -rf /usr/bin/python2.7
ln -s /usr/local/bin/python2.7 /usr/bin/python
ln -s /usr/local/bin/python2.7 /usr/bin/python2
ln -s /usr/local/bin/python2.7 /usr/bin/python2.7
/usr/bin/python -V
/usr/bin/python2 -V
/usr/bin/python2.7 -V
rm -rf /usr/local/bin/python
rm -rf /usr/local/bin/python2
ln -s /usr/local/bin/python2.7 /usr/local/bin/python
ln -s /usr/local/bin/python2.7 /usr/local/bin/python2
python -V
python2 -V
python2.7 -V

3. 下载并安装最新版本python3:
wget https://www.python.org/ftp/python/3.6.2/Python-3.6.2.tgz
tar zxvf Python-3.6.2.tgz
cd Python-3.6.2
./configure
make all
make install
make clean
make distclean
rm -rf /usr/bin/python
rm -rf /usr/bin/python3
rm -rf /usr/bin/python3.6
ln -s /usr/local/bin/python3.6 /usr/bin/python
ln -s /usr/local/bin/python3.6 /usr/bin/python3
ln -s /usr/local/bin/python3.6 /usr/bin/python3.6
/usr/bin/python -V
/usr/bin/python3 -V
/usr/bin/python3.6 -V
rm -rf /usr/local/bin/python
rm -rf /usr/local/bin/python3
ln -s /usr/local/bin/python3.6 /usr/local/bin/python
ln -s /usr/local/bin/python3.6 /usr/local/bin/python3
python -V
python3 -V
python3.6 -V

TAGS:
十二月 3rd, 2017

实现Python连接Mysqln以及应用

python 连接mysql数据库,是python应用的一个非常重要的模块,Pytho连接Mysqln需要连接导入python的mysql模块,通过python连接数据库,我们可以实现对本地的资源状态实现实时监控。

 

1、首先我们需要先安装MySQL模块

1
[root@centos mem]# yum  install  MySQL-python   -y

2、接下来我们就可以直接脚本了

1
2
3
4
5
6
7
8
9
[root@centos pytonjiaoben]# cat mysql.py 
import MySQLdb  as  mysql                               ###这是导入 MySQL-python模块
con = mysql.connect(user="root"passwd="123456", \
                    db="mem", host="127.0.0.1")         ###连接本地的数据库mem,指定数据库的名称,主机地址,用户名和密码
con.autocommit(True)                                    ###设置为自动提交模式,表示把每一个查询操作,作为1个独立的事务处理,马上执行
cur = con.cursor()                                      ###创建1个游标对象
for in range(10):                                     ###这里做个for循环写入数据
   sql = 'insert into mem values(%d, "user%d")'%(i,i)   ###定义sql语句
   cur.execute(sql)    ##执行sql语句

注意:

##数据库和数据表必须是你先创建的,而且mysql一定要设置密码才行。

3、执行结果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
mysql> select * from mem;
+------+---------+
id   | name    |
+------+---------+
|    0 | user0   |
|    1 | user1   |
|    2 | user2   |
|    3 | user3   |
|    4 | user4   |
|    5 | user5   |
|    6 | user6   |
|    7 | user7   |
|    8 | user8   |
|    9 | user9   |

当我们执行脚本后,我们发现数据已经写得数据库里面了

4、现在我们可能会有疑问,这样写进去又有什么用,那好,我们接着写个脚本,关于mysql的应用的。现在我们对服务器的内存使用情况,写入到mysql上,写得mysql上就可以通过flask调用,实现对本地资源实现监控。

我们查看一下我们内存文件

1
2
3
4
5
6
[root@centos pytonjiaoben]# cat /proc/meminfo 
MemTotal:        1528700 kB
MemFree:          224072 kB
Buffers:          130432 kB
Cached:           604432 kB
SwapCached:         8440 kB

6、编写脚本,获取内存的使用量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
[root@centos pytonjiaoben]# cat mem/mysql.py 
# -*- coding:utf-8 -*-
import time
import os
import MySQLdb as mysql
db = mysql.connect(user="root"passwd="123456", db="memory", host="localhost")
db.autocommit(True)
cur=db.cursor()
def saveMem():            ##获取memory的total、free、buff的量
     a="awk 'NR==1{print $2}' /proc/meminfo"
     file = os.popen(a)
     total=int(file.read())
     b="awk 'NR==2{print $2}' /proc/meminfo"
     file =os.popen(b)
     free =int(file.read())
     c="awk 'NR==3{print $2}' /proc/meminfo"
     file = os.popen(c)
     buffer =int(file.read())
     d="awk 'NR==4{print $2}' /proc/meminfo"
     file =os.popen(d)
     cache =int(file.read())
     mem_used=total-free-buffer-cache
     print mem_used/1024
     #mem = mem_used/1024  
     cur_time = int(time.time())
     sql = 'insert into memory (memory, time) value (%s,%s)'%(mem_used,cur_time)
     cur.execute(sql)
while True:
saveMem()
time.sleep(1)   # sleep 1 second

7、查看结果

1
2
3
4
5
[root@centos pytonjiaoben]# python  mem/mysql.py 
562
563
563
563

###查看数据库

1
2
3
4
5
6
7
8
mysql> select * from  memory;
+--------+------------+
| memory |   time     |
+--------+------------+
| 577012 | 1511869204 |
| 577004 | 1511869205 |
| 576872 | 1511869206 |
+--------+------------+

8、我们会发现它会实时获取内存的使用情况,这样我们的目的也达到了,只要有数据输入到mysql中,接下来只要通过flask调用,做成图,就可以实现监控了

十月 27th, 2017

在使用 Python 的开发过程中,除了使用 datetime 标准库来处理时间和日期,还有许多第三方的开源库值得尝试。

1、Arrow

Arrow 是一个专门处理时间和日期的轻量级 Python 库,它提供了一种合理、智能的方式来创建、操作、格式化、转换时间和日期,并提供了一个支持许多常见构建方案的智能模块 API 。简单来说,它可以帮你以更简便的操作和更少的代码来使用日期和时间。其设计灵感主要来源于 moment.js 和 requests 。

Quick start

  1. $ pip install arrow
  1. >>> import arrow
  2. >>> utc = arrow.utcnow()
  3. >>> utc
  4. <Arrow [2013-05-11T21:23:58.970460+00:00]>
  5. >>> utc = utc.replace(hours=-1)
  6. >>> utc
  7. <Arrow [2013-05-11T20:23:58.970460+00:00]>
  8. >>> local = utc.to(‘US/Pacific’)
  9. >>> local
  10. <Arrow [2013-05-11T13:23:58.970460-07:00]>
  11. >>> arrow.get(‘2013-05-11T21:23:58.970460+00:00’)
  12. <Arrow [2013-05-11T21:23:58.970460+00:00]>
  13. >>> local.timestamp
  14. 1368303838
  15. >>> local.format()
  16. ‘2013-05-11 13:23:58 -07:00’
  17. >>> local.format(‘YYYY-MM-DD HH:mm:ss ZZ’)
  18. ‘2013-05-11 13:23:58 -07:00’
  19. >>> local.humanize()
  20. ‘an hour ago’
  21. >>> local.humanize(locale=‘ko_kr’)
  22. ‘1시간 전’

2、Delorean

Delorean 提供了一个相比于 datetime 和 pytz 的更好的抽象,让你处理时间更容易。它有很多有用的处理时区的特性,标准化时区或者从一个时区改变到另外一个时区。

Quick start

  1. from datetime import datetime
  2. import pytz
  3. est = pytz.timezone(‘US/Eastern’)
  4. d = datetime.now(pytz.utc)
  5. d = est.normalize(d.astimezone(est))
  6. return d
  1. from delorean import Delorean
  2. d = Delorean()
  3. d = d.shift(‘US/Eastern’)
  4. return d

3、Pendulum

原生的 datetime 足够应付基本情况,但当面对更复杂的用例时,通常会有的捉襟见肘,不那么直观。 Pendulum 在标准库的基础之上,提供了一个更简洁,更易于使用的 API ,旨在让 Python datetime 更好用。

Quick start

  1. >>> import pendulum
  2. >>> now_in_paris = pendulum.now(‘Europe/Paris’)
  3. >>> now_in_paris
  4. ‘2016-07-04T00:49:58.502116+02:00’
  5. # Seamless timezone switching
  6. >>> now_in_paris.in_timezone(‘UTC’)
  7. ‘2016-07-03T22:49:58.502116+00:00’
  8. >>> tomorrow = pendulum.now().add(days=1)
  9. >>> last_week = pendulum.now().subtract(weeks=1)
  10. >>> if pendulum.now().is_weekend():
  11. …     print(‘Party!’)
  12. ‘Party!’
  13. >>> past = pendulum.now().subtract(minutes=2)
  14. >>> past.diff_for_humans()
  15. >>> ‘2 minutes ago’
  16. >>> delta = past – last_week
  17. >>> delta.hours
  18. 23
  19. >>> delta.in_words(locale=‘en’)
  20. ‘6 days 23 hours 58 minutes’
  21. # Proper handling of datetime normalization
  22. >>> pendulum.create(2013, 3, 31, 2, 30, 0, 0, ‘Europe/Paris’)
  23. ‘2013-03-31T03:30:00+02:00’ # 2:30 does not exist (Skipped time)
  24. # Proper handling of dst transitions
  25. >>> just_before = pendulum.create(2013, 3, 31, 1, 59, 59, 999999, ‘Europe/Paris’)
  26. ‘2013-03-31T01:59:59.999999+01:00’
  27. >>> just_before.add(microseconds=1)
  28. ‘2013-03-31T03:00:00+02:00’

4、dateutil

dateutil 是 datetime 标准库的一个扩展库,几乎支持以所有字符串格式对日期进行通用解析,日期计算灵活,内部数据更新及时。

Quick start

  1. >>> from dateutil.relativedelta import *
  2. >>> from dateutil.easter import *
  3. >>> from dateutil.rrule import *
  4. >>> from dateutil.parser import *
  5. >>> from datetime import *
  6. >>> now = parse(“Sat Oct 11 17:13:46 UTC 2003”)
  7. >>> today = now.date()
  8. >>> year = rrule(YEARLY,dtstart=now,bymonth=8,bymonthday=13,byweekday=FR)[0].year
  9. >>> rdelta = relativedelta(easter(year), today)
  10. >>> print(“Today is: %s” % today)
  11. Today is: 2003-10-11
  12. >>> print(“Year with next Aug 13th on a Friday is: %s” % year)
  13. Year with next Aug 13th on a Friday is: 2004
  14. >>> print(“How far is the Easter of that year: %s” % rdelta)
  15. How far is the Easter of that year: relativedelta(months=+6)
  16. >>> print(“And the Easter of that year is: %s” % (today+rdelta))
  17. And the Easter of that year is: 2004-04-11

5、moment

用于处理日期/时间的 Python 库,设计灵感同样是来源于 moment.js 和 requests ,设计理念源自 Times Python 模块。

Usage

  1. import moment
  2. from datetime import datetime
  3. Create a moment from a string
  4. moment.date(“12-18-2012”)
  5. Create a moment with a specified strftime format
  6. moment.date(“12-18-2012”“%m-%d-%Y”)
  7. # Moment uses the awesome dateparser library behind the scenes
  8. moment.date(“2012-12-18”)
  9. Create a moment with words in it
  10. moment.date(“December 18, 2012”)
  11. Create a moment that would normally be pretty hard to do
  12. moment.date(“2 weeks ago”)
  13. Create a future moment that would otherwise be really difficult
  14. moment.date(“2 weeks from now”)
  15. Create a moment from the current datetime
  16. moment.now()
  17. # The moment can also be UTC-based
  18. moment.utcnow()
  19. Create a moment with the UTC time zone
  20. moment.utc(“2012-12-18”)
  21. Create a moment from a Unix timestamp
  22. moment.unix(1355875153626)
  23. Create a moment from a Unix UTC timestamp
  24. moment.unix(1355875153626, utc=True)
  25. Return a datetime instance
  26. moment.date(2012, 12, 18).date
  27. # We can do the same thing with the UTC method
  28. moment.utc(2012, 12, 18).date
  29. Create and format a moment using Moment.js semantics
  30. moment.now().format(“YYYY-M-D”)
  31. Create and format a moment with strftime semantics
  32. moment.date(2012, 12, 18).strftime(“%Y-%m-%d”)
  33. Update your moment’s time zone
  34. moment.date(datetime(2012, 12, 18)).locale(“US/Central”).date
  35. Alter the moment’s UTC time zone to a different time zone
  36. moment.utcnow().timezone(“US/Eastern”).date
  37. Set and update your moment‘s time zone. For instance, I’on the
  38. # west coast, but want NYC’s current time.
  39. moment.now().locale(“US/Pacific”).timezone(“US/Eastern”)
  40. In order to manipulate time zones, a locale must always be set or
  41. # you must be using UTC.
  42. moment.utcnow().timezone(“US/Eastern”).date
  43. # You can also clone a moment, so the original stays unaltered
  44. now = moment.utcnow().timezone(“US/Pacific”)
  45. future = now.clone().add(weeks=2)

6、When.py

提供对用户非常友好的特性来帮助执行常见的日期和时间操作。

Usage

八月 27th, 2017

1、环境准备

主机名 IP 系统 Python版本
Python-01 192.168.10.9 CentOS release 6.9 (Final) 3.5.4

参考:https://www.shiyanlou.com/courses/370/labs/1191/document

2、原理

字符画是一系列字符的组合,可以把字符看作是比较大块的像素,一个字符能表现一种颜色(暂且这么理解吧),字符的种类越多,可以表现的颜色也越多,图片也会更有层次感。

灰度值指范围一般从0到255,白色为255,黑色为0,故黑白图片也称灰度图像。

任何颜色都由红、绿、蓝三基色组成,假如原来某点的颜色为RGB(R,G,B),本次实验可以用以下公式来转换灰度:

1
gray = 0.2126 * + 0.7152 * + 0.0722 * b

3、实验

本次实验的核心是pillow库的Image模块和argparse模块。

3.1 图像处理库pillow

Pillow是Python里的图像处理库,支持Python3.X,提供了广泛的文件格式支持和强大的图像处理能力,主要包括图像储存、图像显示、格式转换以及基本的图像处理操作等。

Image类使用说明参考:http://pillow.readthedocs.io/en/latest/reference/Image.html

3.2 安装pillow库

直接用Python3自带的pip安装即可:

1
pip install pillow

widonws端可以用以下命令安装:

1
python3 -m pip install pillow

3.3 argparse模块

argparse模块使编写用户友好的命令行界面变得更容易。程序只需定义好它要求的参数,然后argparse将负责如何从sys.argv中解析出这些参数。argparse模块还会自动生成帮助和使用信息并且当用户赋给程序非法的参数时产生错误信息。

3.3.1 ArgumentParser对象

add_argument()方法必须知道期望的是可选参数,例如-o 或者–output参数用来设置输出文件:

1
2
parser = argparse.ArgumentParser()
parser.add_argument('-o''--output')

add_argument()的default关键字参数,其默认值为None,指出如果命令行参数没有出现时它们应该是什么值,还可以设定其类型type,例如设定输出字符画的宽:

1
parser.add_argument('--width'type = int, default = 80)

3.4 准备图片

wKioL1mfj2mRI9J2AAB09TbRWOY101.jpg

3.5 源码

源码在Windows、CentOS和Ubuntu环境均验证成功。

1
vim test.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#!/usr/bin/env python3
from PIL import Image
import argparse
# 命令行输入参数处理
parser = argparse.ArgumentParser()
parser.add_argument('file')     # 输入文件
parser.add_argument('-o''--output')   # 输出文件
# 输出字符画宽,默认值为80
parser.add_argument('--width'type = int, default = 80)
# 输出字符画高,默认值为80
parser.add_argument('--height'type = int, default = 80
# 获取参数
args = parser.parse_args()
IMG = args.file
WIDTH = args.width
HEIGHT = args.height
OUTPUT = args.output
# 灰度值小(暗)的用列表开头的符号,灰度值大(亮)的用列表末尾的符号。
ascii_char = list("$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\|()1{}[]?-_+~<>i!lI;:,\"^`'. ")
# 将256灰度映射到列表的70个字符上
def get_char(r,g,b,alpha = 256):
    if alpha == 0:
        return ' '
    length = len(ascii_char)
    gray = int(0.2126 * + 0.7152 * + 0.0722 * b)
    unit = (256.0 + 1)/length
    return ascii_char[int(gray/unit)]
if __name__ == '__main__':
    im = Image.open(IMG)
    im = im.resize((WIDTH,HEIGHT), Image.NEAREST)
    txt = ""
    for in range(HEIGHT):
        for in range(WIDTH):
            txt += get_char(*im.getpixel((j,i)))
        txt += '\n'
    print(txt)
    # 字符画输出到文件
    if OUTPUT:
        with open(OUTPUT,'w') as f:
            f.write(txt)
    else:
        with open("output.txt",'w') as f:
            f.write(txt)

3.6 运行结果

1
python3 test.py timg.jpg
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
                                      ....  ..
                           ......lB&],,,,,,,+Mp'...
                            ..8c,,,,,,,,,,,,,,,,M"`
                        . '&<,,,,,,,,,,,,,,,,,,,,,!U .
                       '+aI,,,,,,,,,,,,,,,,,,,,,,,,;|f.'
                      'ox:,,,,,,,,,,,,,,,,,,,,,,,,,,,">o\..
                     o",:,,,,,,,,,,,,,,,,,,,,,,,,,,,,,"::c@.
                  . &:"I,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,f^,,lJ.
                  ^>";,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,M,,,`&
                .';",&,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,"!",,,:}.
                ^,,,:,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#l,,,":]
               '",,,,^,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,;!,,,,,Ix..
              ',,,,,m,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,M!,,,,,,Z`
             'Z,,,,,M,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,l!,,,,,,^.`
           ..h:,,,,"*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,ii:,,,,,,}.
            ti,,,,,:[,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,k!,,,,,,,M
           .I,,,,,,,:",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,&!,,,,,,,,v
           k,,,,,,,l:,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,_!:,,,,,,,"'
          Y:,,,,,,,!:,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,l!l,,,,,,,:#
         '[,,,,,,,,l:",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,ii!,,,,,,,:0
       . o^,,,,,,,!l:,,,,,",,",,,,,,,,,,,,,,,,,,":lz(,,,",,;]!:,,,,,,,0&
       .`O,,,,,,,:!!",,,j**WWMW[,,,,,,,,,,,,,,,vMMMWMM8o,,,,{!;,,,,,,,0Z.
       .80,,,,,,,:!l:,,,8,,""":",,,,,,,,,,,,,,,M",:,:::I,,,,(!!,,,,,,"0QW
      .`00",,,,,:!l{,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,^?>!,,,,,,,00Q..
     .'W00",,,,,:!1*:",,,,::,,,,,,,,,,,",,,,,,,,,,,,,,,,,,,,^^!",,,,,"00Ou
     ..000",,,,,!I\JjmW;,",,,,,,,,,,,,-8^,,,,,,,,,,,,,,:,,&&,.`p;,,,,"000a.
      %000,,,,,,!)[nxxn*;:,,,,,,,,,,,,^,,,,,,,,,,,,,,,:Izunu#..'8I,,,"000O^
     .0000:,,,,;>}Mxxxxx8:,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0rxxxj`   #l,,"0000B
     M0000,,,,,!1vnnxxxx\:,,,,,,,,,,,,,,,,,,,,,,,,,,,,,vxxxxr@    ';",0000k
    .O0000I,,,!(bWxxxxxxf:,,,,,,,,,,,,:"",,,,,,,,,,,,:Ixxxxxxx'    'W,00000
    .00000},,;>a'uxxxxxx%",,,,,,,,,,,"%ujM;:,,,,,,,,,,/xxxxxxxW    . M00000,
    W00000n,,ip :xxxxxnt:,,,,!W:,,^#Mxnxxnn%C&M8WW;,,,"jxxxxunQ      ."q000o.
    000000J,-' .#xrxxxm;",,,,:;",:,"Mxxxnxv^:",":,",,,,Wnxxxv::&+    .`'800Z'
   !000000Qo ..#,,"8W^,,,,,,,,,,,,,,,Mnnxu8,,,,,,,,,,,,,,&hxB,,,,#''   . #0OJ
  .M0000QQ# .Wl,,,:o",,,,,,,,,,,,,,,,:&nx/;,,,,,,,,,,,,,,,,:<,,,,,J'       *M.
  `O000L*.. .,,,,,,;",,,,,,,,,,,,,,,,,,z*^,,,,,,,,,,,,,,,,,,M,,,,,,&.      .#.
  BQ00&`   .m,,,,,:Z,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,IZ,,,,,:.
  B#M..     :,,,,^#!:,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,!:J,,,,,!.
           .",,,,;^ul!:,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,":i)Cl,,,,l!.
        .  `>,,,,,":Yfi!!;,,,,,,,,,,,,,,,,,,,,,,,,,,::I!I8X!I,,,,,l!.
            ;!,,,,,,":{#WIl!!!!!I;:,""",::;IIl!i!!llf&&{11!;,,,,,!!r'
            Ll!,,,,,,:,"?(t]jq8&MWWWM&&&&&##M8*X1)(1()1ll!,,,,,,I!!f
             *l!:,,,,,,,,:"::l!<_+-][{{{11{{11{[_!:!!l!:,",,,,,:l!X.
             "B!!!;,,,,,,,,,,,,,","",,,,",,,",,,:,,",:,,,,:,,:!!!a..
            .. *l!!!!",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,!!!!i*.      .
                v!!!!!:,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,li>!o
                .<*i!!,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,l;` .
                  .jJI,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,!-
                    `I,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,!!
                    .I,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,:! .
                    W!,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,id
                  ..~!,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,!#.
                   .I!,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,!!
                  .+!,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,:i
                   %!,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,iX
                   _!,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,!%
                  .I;,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,"I
                  '!,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,i..
                  Y!,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,!;.
                 'M!,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0.
                . ?;,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#.
                ..I:,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,:8.
                 .l,,,,,,,,,,,,,,,,,::::::::::::::::::::::::,!&.
                  -,,,,,,,,,,,,,,,,::::::::::::::::::::::::::lh.
                . #,,,,,,,,,,,,,,,,:::::::;:::;;:::;:::::::::l1.
                   ,,,,,,,,,,,,,,,,::::;;;;;;;;;:;;;;;;;;;;;!<
                  .*I::,,,,,,,,,,,,,,,;:;:;;;;;;;;;;;;;;;;;;:M
                    #~!;,:,,,,,:,:li!!!!li!!!!!!!!!;;;;;;;;;_
                     1M;>l>!!!ill!!!}##&W#W&&1>l>l!!!!!!I;Ik .
                    (>~((fk#oaC|)|))))))))))))(\(#oMC1<ao#xW
                    aC<!i!!!((((()()))))))))))))(()(\\)){)<!
                    \~+!!!i(())))))))))))))))))))))))(i!!!!&Q.
                    (aa!!@))()))))))))))())))))))))()){I!!M!!
                     ;|["'            .               )/&lt\
                       ...                            . .;..

当然,也可以调整默认参数,来缩小输出比例:

1
python3 test_img.py  --width 30 --height 30 timg.jpg

image

4、总结

熟悉了argparse模块和Image模块。argparse是Python用于解析命令行参数和选项的标准模块,举例:

1
2
3
4
5
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("echo")
args = parser.parse_args()
print args.echo
1
2
$ python xx.py test1
test1
TAGS:
七月 20th, 2017
动态类型(dynamic typing)是Python另一个重要的核心概念。我们之前说过,Python的变量(variable)不需要声明,而在赋值时,变量可以重新赋值为任意值。这些都与动态类型的概念相关。 

动态类型

在我们接触的对象中,有一类特殊的对象,是用于存储数据的。常见的该类对象包括各种数字,字符串,表,词典。在C语言中,我们称这样一些数据结构为变量。而在Python中,这些是对象。

对象是储存在内存中的实体。但我们并不能直接接触到该对象。我们在程序中写的对象名,只是指向这一对象的引用(reference)。

 

引用和对象分离,是动态类型的核心。引用可以随时指向一个新的对象:

a = 3
a = 'at'

第一个语句中,3是储存在内存中的一个整数对象。通过赋值,引用a指向对象3。

第二个语句中,内存中建立对象‘at’,是一个字符串(string)。引用a指向了’at’。此时,对象3不再有引用指向它。Python会自动将没有引用指向的对象销毁(destruct),释放相应内存。

(对于小的整数和短字符串,Python会缓存这些对象,而不是频繁的建立和销毁。)

a = 5
b = a
a = a + 2

再看这个例子。通过前两个句子,我们让a,b指向同一个整数对象5(b = a的含义是让引用b指向引用a所指的那一个对象)。但第三个句子实际上对引用a重新赋值,让a指向一个新的对象7。此时a,b分别指向不同的对象。我们看到,即使是多个引用指向同一个对象,如果一个引用值发生变化,那么实际上是让这个引用指向一个新的引用,并不影响其他的引用的指向。从效果上看,就是各个引用各自独立,互不影响。

其它数据对象也是如此:

L1 = [1,2,3]
L2 = L1
L1 = 1

但注意以下情况

L1 = [1,2,3]
L2 = L1
L1[0] = 10
print L2

在该情况下,我们不再对L1这一引用赋值,而是对L1所指向的表的元素赋值。结果是,L2也同时发生变化。

原因何在呢?因为L1,L2的指向没有发生变化,依然指向那个表。表实际上是包含了多个引用的对象(每个引用是一个元素,比如L1[0],L1[1]…, 每个引用指向一个对象,比如1,2,3), 。而L1[0] = 10这一赋值操作,并不是改变L1的指向,而是对L1[0], 也就是表对象的一部份(一个元素),进行操作,所以所有指向该对象的引用都受到影响。

(与之形成对比的是,我们之前的赋值操作都没有对对象自身发生作用,只是改变引用指向。)

 

列表可以通过引用其元素,改变对象自身(in-place change)。这种对象类型,称为可变数据对象(mutable object),词典也是这样的数据类型。

而像之前的数字和字符串,不能改变对象本身,只能改变引用的指向,称为不可变数据对象(immutable object)。

我们之前学的元组(tuple),尽管可以调用引用元素,但不可以赋值,因此不能改变对象自身,所以也算是immutable object.

从动态类型看函数的参数传递

函数的参数传递,本质上传递的是引用。比如说:

复制代码
def f(x):
    x = 100
    print x

a = 1
f(a)
print a
复制代码

参数x是一个新的引用,指向a所指的对象。如果参数是不可变(immutable)的对象,a和x引用之间相互独立。对参数x的操作不会影响引用a。这样的传递类似于C语言中的值传递。

如果传递的是可变(mutable)的对象,那么改变函数参数,有可能改变原对象。所有指向原对象的引用都会受影响,编程的时候要对此问题留心。比如说:

复制代码
def f(x):
    x[0] = 100
    print x

a = [1,2,3]
f(a)
print a
复制代码

动态类型是Python的核心机制之一。可以在应用中慢慢熟悉。

总结

引用和对象的分离,对象是内存中储存数据的实体,引用指向对象。

可变对象,不可变对象

函数值传递

 

 

 

作者:Vamei 出处:http://www.cnblogs.com/vamei