《UNIX/Linux 系统管理技术手册(第四版)》——2.5 Python脚本编程

简介:

本节书摘来自异步社区《UNIX/Linux 系统管理技术手册(第四版)》一书中的第2章,第2.5节,作者:【美】Evi Nemeth , Garth Snyder , Trent R.Hein , Ben Whaley著,更多章节内容可以访问云栖社区“异步社区”公众号查看

2.5 Python脚本编程

UNIX/Linux 系统管理技术手册(第四版)
随着项目变得越来越大、越来越复杂,面向对象的设计和实现所带来的好处,也就变得越来越清楚。Perl错过了大概5年时间,没有提供OO特性,虽然它后来又拼命去追赶,但Perl版的面向对象编程仍然显得有点儿牵强。

本节介绍Python 2。Python 3尚在开发之中,可能在本书没过时之前就能发布。但是和Perl 6不一样的是,它看上去更像是一种增量更新。

有着很强OO背景的工程师通常会喜欢Python和Ruby,这两种脚本编程语言都有一种明显的OO特质。目前,Python似乎正处于采纳曲线的下降沿,所以对于系统管理来说,它是一种相当流行的工具。包括OpenSolaris在内的几种操作系统,主要利用了Python的脚本功能。与此相对照,Ruby仍然主要用于Web开发,很少用作一般性的脚本编程。

Guido van Rossum发明了Python。与Perl相比,Python的代码更好写,也更好读。Python提供了一种易于理解的语法,即使没开发过这种代码,也很容易掌握。如果觉得要记住用哪种比较操作符很累人,那么会喜欢上Python整齐划一的方式。Python还提供更多的数据类型,有些系统管理员会发现它们很有用。

如果系统上还没装好Python,可以看看操作系统提供商或者发布方给出的软件包清单。它是一种极其常见的软件包,应该到处都有。如果没找到,可以从python.org下载Python的源代码。这个地方也一个集中位置,可以找到其他人开发的附加模块。

对于Python而言,要想获得比我们在这儿给出的介绍更全面的内容,Mark Pilgrim的Dive Into Python是一个非常好的起步点。从diveintopython.org可以(免费)阅读或者下载这份文档,也可以购买Apress出版的印刷版图书。在2.7节里可以找到完整的参考文献。

2.5.1 Python快速入门
还像往常一样,我们先从一个简单“Hello,world!”脚本开始。果不其然,Python的“Hello, world!”几乎和Perl的一模一样。

#!/usr/bin/python print "Hello,  world!"

要让这个脚本可以运行,只要设置它的可执行位,扩展直接调用python来解释这个脚本:

$ chmod +x  helloworld

$ ./helloworld

Hello, world!

这样的一行程序不能体现出Python对传统的突破,这一突破恶名在外,也就是说,缩行在逻辑上很重要。Python不用花括号、方括号,或者begin和end来界定代码块。处于同一缩进级别的语句自动构成代码块。缩行的风格(空格或者制表符,缩进的深度)则无关紧要。Python的代码分块最好用例子来展示,所以下面就用一条if-then-else语句来说明:

#!/usr/bin/python import sys

a = sys.argv[1]

if a == "1":

print 'a is  one'

print 'This is  still the then clause of  the if statement.'

else:

print 'a is',  a

print 'This is  still the else  clause of  the if statement.'
print 'This is  after the if statement.'

第三行导入sys模块,它包含数组argv。then和else子句都有两行,每一部分都缩进到相同的层次。最后的print语句在if语句之外。和在Perl里的情况一样,Python的print语句也接受任意数量的参数。但和Perl不一样的是,Python自动在每对参数之间都插入一个空格,并提供一个换行符。可以在print行的末尾多加一个逗号,消除这个换行符;参数为空则告诉print不要输出换行符。

在一行末尾的冒号一般是该行引入的一个联系符,它和随后的一个缩进块关联到一起。

$ python blockexample 1

a is  one

This is  still the then clause of  the if statement. This is  after the if statement.

$ python blockexample 2

a is  2

This  is  still the else  clause of  the if statement. This is  after the if statement.

Python的缩行惯例使得代码格式上的灵活度更低了,但它也有优点,即不同的人所编写的代码看上去都一样,而且还意味着不需要搞得代码里到处都有分号,而这些烦人的分号就只为了结束语句。

Python里的注释用一个井号(#)开头,一直持续到行尾,同bash和Perl里的用法一样。

在代码行用反斜线结尾,就可以把长长的代码行分成多行来写。这样做的时候,只有第一行代码的缩进才重要。不过,如果愿意,可以让后续的代码行都缩进。即使没有出现反斜线,但圆括号、方括号或者花括号不配对的代码行仍会自动触发续行,但如果出现这样的情况,可以在代码里包含反斜线,让代码的结构更清晰。

有些剪切和粘贴操作会把制表符(tab)转换为空格,除非知道自己要什么,否则这会让人抓狂。黄金法则是,绝对不要混用制表符和空格;缩进要么用制表符,要么用空格。许多软件采用传统的假设,让制表符应该等于8个空格的距离,对于代码的可读性来说,这确实缩进得太厉害了。大多数Python用户似乎都偏向于采用空格,而且缩进4个字符。

不管决定怎样处理缩行的问题,大多数编辑器都有若干选项,要么只用空白让制表符为非法,要么让空格和制表符显示得不一样,从而帮助用户搞得清楚。在万不得已的情况下,还可以用expand命令把制表符转为空格,或者通过perl -pe命令用一个更容易看到的字符串替换制表符。

2.5.2 对象、字符串、数、列表、字典、元组和文件
Python中所有的数据类型都是对象,比起Perl中的数据类型来说,这一点让它们更强大,也更灵活。

在Python里,列表用方括号而不是圆括号括起来。数组的索引(下标)从0开始,在本章介绍的3种脚本编程语言中,这是为数不多的几种没有变化的概念之一。

Python里新出现了一种叫做“元组(tuple)”的数据类型,它实质上是不能变的列表。元组比数组更快,对于实际上不应该被修改的数据来说,用元组表示更合适。除了用圆括号而不是方括号做定界符之外,元组的语法和列表的一样。因为(thing)看上去是一个简单的代数表达式,因此,对于只包含一个元素的元组,需要用一个额外的逗号来消除它们的含糊意思:(thing, )。

下面是Python中出现的几种基本变量和数据类型:

#!/usr/bin/python name = 'Gwen'

rating = 10

characters = [ 'SpongeBob',  'Patrick', 'Squidward' ]

elements = ( 'lithium', 'carbon', 'boron' )

print "name:\t%s\nrating:\t%d" % (name,  rating)

print "characters:\t%s" % characters print "elements:\t%s" % (elements, )

这个例子产生的输出如下:

$ python objects name: Gwen rating: 10

characters: ['SpongeBob',  'Patrick', 'Squidward']

elements: ('lithium',  'carbon', 'boron')

Python中的变量不会从语法上体现出来,也不会做类型声明,但是它们所指的对象的确有一种支持类型。在大多数情况下,Python不会替用户自动做类型转换,但是单个函数或者操作符可以做转换。例如,不显式地把数值转换为它的字符串表示形式的话,就不能把一个数和一个字符串(用操作符+)连接起来。不过,格式化操作符和语句会强制把所有东西都转为字符串形式。每个对象都有一个字符串表示。

字符串格式化操作符%很像C或者Perl语言里的sprintf函数,但它可以用在字符串出现的任何地方。它是一个双目操作符,左边是字符串,右边是要插入的数值。如果要插入一个以上的数值,那么必须用元组来表示这些值。

Python字典和Perl的哈希一样;也就是说,它是“键/值”对的一个列表。字典常量用花括号括起来,每一对“键/值”都用一个冒号分隔。

#!/usr/bin/python

ordinal = {  1 : 'first', 2 : 'second', 3 : 'third' } print "The  ordinal array contains", ordinal print "The  ordinal of  1 is", ordinal[1]

在使用上,Python的字典又非常像数组,区别在于下标(键)可以是对象而不只是整数。

$ python dictionary

The ordinal array contains {1: 'first', 2: 'second', 3: 'third'} The  ordinal of  1 is  first

Python用对象所关联的方法把打开的文件按对象来处理。顾名思义,readline方法读取一行,所以下面的例子从/etc/passwd文件读取并打印两行内容。

#!/usr/bin/python

f = open('/etc/passwd',  'r')

print f.readline(), print f.readline(), f.close()

$ python fileio

at:x:25:25:Batch jobs  daemon:/var/spool/atjobs:/bin/true bin:x:1:1:bin:/bin:/bin/true

print语句里最后的逗号消除了换行符,因为每行在从原来的文件读入的时候就已经带一个换行符了。

2.5.3 确认输入的例子
下面的脚本片段是Python版的确认输入的程序,我们现在已经很熟悉这个例子了。它展示了子例程和命令行参数的用法,还体现了其他两种Python化的特性。

#!/usr/bin/python import sys

import os

def  show_usage(message, code = 1):

print message

print "%s:  source_dir dest_dir"  % sys.argv[0]

sys.exit(code)

if len(sys.argv) != 3:

show_usage("2 arguments  required; you  supplied %d"  % (len(sys.argv) - 1))

elif  not os.path.isdir(sys.argv[1]):

show_usage("Invalid source directory")

elif  not os.path.isdir(sys.argv[2]):

show_usage("Invalid destination  directory")

source, dest = sys.argv[1:3]

print "Source Directory is", source print "Destination Directory is", dest

除了导入sys模块之外,我们还导入了os模块,从而可以使用os.path.isdir这个例程。注意,对于模块定义的任何代号来说,import命令不会提供访问它们的捷径;必须使用从模块名开始的全名。

例程show_usage的定义里给退出码赋予了一个默认值,万一调用程序没有显式地指定这个参数,就用这个默认值退出。既然所有的数据类型都是对象,所以用引用来给函数传参。

数组sys.argv在第0个位置保存有该脚本的名字,所以它的长度比实际提供的命令行参数个数正好多1。sys.argv[1:3]这样的形式表示一个数组段。有意思的是,数组段不包括指定范围里最后的那个元素,所以这个数组段只有sys.argv[1]和sys.argv[2]两个元素。可以简单地用sys.argv[1:]把从第二个开始的所有元素都包括进来。

同bash和Perl一样,Python也有专门的一种“else if”条件;其关键字是elif。Python也没有case或者switch语句。

给soure和dest变量的平行赋值与Perl有点儿不一样,因为这两个变量本身不在一个列表里。两种形式的平行赋值在Python里都可以。

Python给数值和字符串的比较运算符都一样。“不相等”的比较运算符是!=,但却没有!这样的单目运算符;这样的单目运算符是not。也要搞清楚布尔运算符and和or。

2.5.4 循环
下面的代码片段用一个for…in结构从1循环到10。

for counter  in range(1, 10):

print counter,

和前面例子里的数组段一样,这个范围的右端点实际上没有包括进来。输出值只有1到9。

1 2 3 4 5 6 7 8 9

这是Python里唯一的for循环类型,但它功能很强大。Python的for语句有几项特性,有别于其他语言。

数值范围没有什么特殊之处。任何对象都可以支持Python的循环模型,而且最常见的对象都支持。可以通过一个字符串(按逐个字符)、一个列表、一个文件(按逐个字符、逐行或者逐块),以及一个数组段等。

循环可以产生多个值,循环变量也可以有多个。在每次循环的开头进行的赋值,就和Python正常的多重赋值一样。

for和while循环都可以在末尾加上else子句。只有当循环正常终止之后,才执行这个else子句,这和通过一条break语句退出正好相反。这一功能乍看起来似乎与直觉相反,但它能很好地处理某些用例。

下面的脚本示例接受命令行上的一个正则表达式,把它同一个列表进行匹配,列表里是白雪公主中七个小矮人的名字及其衣服的颜色。该脚本打印第一个匹配的结果,而且匹配正则表达式的部分两边用下划线区分出来。

#!/usr/bin/python import sys

import re

suits = {  'Bashful':'red', 'Sneezy':'green', 'Doc':'blue', 'Dopey':'orange',

'Grumpy':'yellow', 'Happy':'taupe',  'Sleepy':'puce' }

pattern = re.compile("(%s)" % sys.argv[1])

for  dwarf, color in  suits.items():

if pattern.search(dwarf)  or  pattern.search(color):

print "%s's  dwarf suit is  %s." % \

(pattern.sub(r"_\1_",  dwarf), pattern.sub(r"_\1_", color))

break

else:

print "No  dwarves or  dwarf suits matched the pattern."

下面是一些输出的例子:

$ python  dwarfsearch  '[aeiou]{2}'

Sn_ee_zy's dwarf suit is  gr_ee_n.

$ python dwarfsearch go

No  dwarves or  dwarf suits matched the pattern.

给suits赋值的语句,展示了Python用于字典常量的编码方式。suits.items()方法是“键/值”对的迭代器——每次循环都提取一个小矮人的名字和一种衣服颜色。如果只想通过键做循环,只需要把代码写为for dwarf in suits。

Python通过它的re模块实现对正则表达式的处理。Python语言本身没有任何有关正则表达式的功能,所以用Python处理正则表达式比用Perl要稍微麻烦一点儿。在本例中,正则表达式的pattern一开始由compile方法,用圆括号括起来第一个命令行参数进行编译,形成了一个捕获组。接着,用正则表达式对象的search和sub方法测试和修改字符串。还可以像函数那样直接调用re.search等方法,把正则表达式当做第一个参数来用。替换字符串里的1是反过去引用第一个捕获组的内容。

相关文章
|
2天前
|
机器学习/深度学习 人工智能 自然语言处理
【深度学习】Python之人工智能应用篇——音频生成技术
音频生成是指根据所输入的数据合成对应的声音波形的过程,主要包括根据文本合成语音(text-to-speech)、进行不同语言之间的语音转换、根据视觉内容(图像或视频)进行语音描述,以及生成旋律、音乐等。它涵盖了声音结构中的音素、音节、音位、语素等基本单位的预测和组合,通过频谱逼近或波形逼近的合成策略来实现音频的生成。 音频生成技术的发展主要依赖于深度学习模型,如循环神经网络(RNN)、长短时记忆网络(LSTM)、Transformer等。这些模型通过学习大量的音频数据,能够自动生成与人类发音相似甚至超越人类水平的音频内容。近年来,随着大规模预训练模型的流行,如GPT系列模型、BERT、T5等,
12 7
【深度学习】Python之人工智能应用篇——音频生成技术
|
2天前
|
机器学习/深度学习 人工智能 算法
【深度学习】python之人工智能应用篇——图像生成技术(二)
图像生成是计算机视觉和计算机图形学领域的一个重要研究方向,它指的是通过计算机算法和技术生成或合成图像的过程。随着深度学习、生成模型等技术的发展,图像生成领域取得了显著的进步,并在多个应用场景中发挥着重要作用。
15 9
|
2天前
|
机器学习/深度学习 人工智能 自然语言处理
【自然语言处理】python之人工智能应用篇——文本生成技术
文本生成是指使用自然语言处理技术,基于给定的上下文或主题自动生成人类可读的文本。这种技术可以应用于各种领域,如自动写作、聊天机器人、新闻生成、广告文案创作等。
17 8
|
1天前
|
开发工具 git Python
通过Python脚本git pull 自动重试拉取代码
通过Python脚本git pull 自动重试拉取代码
81 4
|
2天前
|
机器学习/深度学习 人工智能 自然语言处理
【机器学习】python之人工智能应用篇--代码生成技术
代码生成技术是人工智能与软件工程交叉领域的一项重要技术,它利用机器学习、自然语言处理和其他AI算法自动编写或辅助编写计算机程序代码。这一技术旨在提高编程效率、降低错误率,并帮助非专业开发者快速实现功能。以下是代码生成技术的概述及其典型应用场景。
15 6
|
4天前
|
弹性计算 API 开发工具
揭秘Python与阿里云API的神秘邂逅!流式处理的魔法之旅,一场颠覆想象的技术盛宴!
【8月更文挑战第15天】在数字世界的广阔舞台上,Python与阿里云API的相遇,就像是一场命中注定的邂逅。它们携手共舞,为我们带来了流式处理的魔法之旅。本文将揭开这场神秘邂逅的面纱,带你领略Python与阿里云API之间的奇妙互动。让我们一起踏上这场颠覆想象的技术盛宴,探索流式处理的无限可能!
21 7
|
2天前
|
机器学习/深度学习 人工智能 自然语言处理
【人工智能】python之人工智能应用篇--数字人生成技术
数字人生成技术是基于人工智能技术和计算机图形学技术创建的虚拟人物形象的技术。该技术能够模拟人类的外貌、声音、动作和交流能力,为多个领域带来创新的应用可能性。数字人的本质是将所有信息(数字和文字)通过数字处理(如计算机视觉、语音识别等)再进行表达的过程,形成具有人类形态和行为的数字产物。 数字人的生成涉及到多种技术,如3D重建技术,使用三维扫描仪扫描人的外观、五官等,并通过3D模型重建三维人;虚拟直播技术,使用计算机技术生成人物或实体,并且可以实时直播、录制;数字人体数据集技术,利用数据构建数字人模型以及训练虚拟现实引擎等
9 4
|
2天前
|
机器学习/深度学习 人工智能 自然语言处理
【深度学习】python之人工智能应用篇——视频生成技术
视频生成技术是一种基于深度学习和机器学习的先进技术,它使得计算机能够根据给定的文本、图像、视频等单模态或多模态数据,自动生成符合描述的、高保真的视频内容。这种技术主要依赖于深度学习模型,如生成对抗网络(GAN)、自回归模型(Auto-regressive Model)、扩散模型(Diffusion Model)等。其中,GAN由两个神经网络组成:一个生成器用于生成逼真的图像或视频,另一个判别器用于判断生成的图像或视频是否真实。通过不断的对抗学习,生成器和判别器共同优化,以产生更高质量的视频。
9 2
|
2天前
|
机器学习/深度学习 人工智能 自然语言处理
【机器学习】python之人工智能应用篇——3D生成技术
在Python中,人工智能(AI)与3D生成技术的结合可以体现在多个方面,比如使用AI算法来优化3D模型的生成、通过机器学习来预测3D模型的属性,或者利用深度学习来生成全新的3D内容。然而,直接通过AI生成完整的3D模型(如从文本描述中生成)仍然是一个活跃的研究领域。 3D生成技术是一种通过计算机程序从二维图像或文本描述自动创建三维模型的过程。这一技术在近年来得到了飞速的发展,不仅为游戏、动画和影视行业带来了革命性的变革,还在虚拟现实、增强现实以及工业设计等多个领域展现出了巨大的应用潜力
7 2
|
2天前
|
机器学习/深度学习 人工智能 自然语言处理
【机器学习】python之人工智能应用篇--游戏生成技术
游戏生成技术,特别是生成式人工智能(Generative Artificial Intelligence, 简称Generative AI),正逐步革新游戏开发的多个层面,从内容创作到体验设计。这些技术主要利用机器学习、深度学习以及程序化内容生成(Procedural Content Generation, PCG)来自动创造游戏内的各种元素,显著提高了开发效率、丰富了游戏内容并增强了玩家体验。以下是生成式AI在游戏开发中的几个关键应用场景概述
6 2