所以你们要效法神,好像蒙慈爱的儿女一样。也要凭爱心行事,正如基督爱我们,为我们舍了自己,当作馨香的供物与祭物献与神。至于淫乱并一切污秽,或是贪婪,在你们中间连提都不可,方合圣徒的体统。(EPHESIANS 5:1-3)

标准库(2)

python标准库内容非常多,有人专门为此写过一本书。在本教程中,我将根据自己的理解和喜好,选几个呈现出来,一来显示标准库之强大功能,二来演示如何理解和使用标准库。

sys

这是一个跟Python解释器关系密切的标准库,前面已经使用过sys.path.append()

>>> import sys
>>> print sys.__doc__

显示了sys的基本文档,第一句话概括了本模块的基本特点。

This module provides access to some objects used or maintained by the
interpreter and to functions that interact strongly with the interpreter.

在诸多sys函数和属性中,选择常用的(应该说是我觉得常用的)来说明。

sys.argv

sys.argv是专门用来向python解释器传递参数,名曰“命令行参数”。

先解释什么是命令行参数。

$ python --version
Python 2.7.6

这里的--version就是命令行参数。如果你使用python --help可以看到更多:

$ python --help
usage: python [option] ... [-c cmd | -m mod | file | -] [arg] ...
Options and arguments (and corresponding environment variables):
-B     : don't write .py[co] files on import; also PYTHONDONTWRITEBYTECODE=x
-c cmd : program passed in as string (terminates option list)
-d     : debug output from parser; also PYTHONDEBUG=x
-E     : ignore PYTHON* environment variables (such as PYTHONPATH)
-h     : print this help message and exit (also --help)
-i     : inspect interactively after running script; forces a prompt even
         if stdin does not appear to be a terminal; also PYTHONINSPECT=x
-m mod : run library module as a script (terminates option list)
-O     : optimize generated bytecode slightly; also PYTHONOPTIMIZE=x
-OO    : remove doc-strings in addition to the -O optimizations
-R     : use a pseudo-random salt to make hash() values of various types be
         unpredictable between separate invocations of the interpreter, as
         a defense against denial-of-service attacks

只选择了部分内容摆在这里。所看到的如-B, -h之流,都是参数,比如python -h,其功能同上。那么-h也是命令行参数。

sys.arg在Python中的作用就是这样。通过它可以向解释器传递命令行参数。比如:

#!/usr/bin/env python
# coding=utf-8

import sys

print "The file name: ", sys.argv[0]        #Python 3的读者,请自行修改为print()函数形式,下同,从略
print "The number of argument", len(sys.argv)
print "The argument is: ", str(sys.argv)

将上述代码保存,文件名是22101.py。然后如此做:

$ python 22101.py
The file name:  22101.py
The number of argument 1
The argument is:  ['22101.py']

将结果和前面的代码做个对照。

  • $ python 22101.py中,“22101.py”是要运行的文件名,同时也是命令行参数,是前面的python这个指令的参数。其地位与python -h中的参数-h是等同的。
  • sys.argv[0]是第一个参数,就是上面提到的22101.py,即文件名。

如果这样来试试:

$ python 22101.py beginner master www.itdiffer.com
The file name:  22101.py
The number of argument 4
The argument is:  ['22101.py', 'beginner', 'master', 'www.itdiffer.com']

在这里用sys.arg[1]得到的就是beginner,依次类推。

sys.exit()

这个方法的意思是退出当前程序。

Help on built-in function exit in module sys:

exit(...)
    exit([status])

    Exit the interpreter by raising SystemExit(status).
    If the status is omitted or None, it defaults to zero (i.e., success).
    If the status is an integer, it will be used as the system exit status.
    If it is another kind of object, it will be printed and the system
    exit status will be one (i.e., failure).

从文档信息中可知,如果用sys.exit()退出程序,会返回SystemExit异常。这里先告知读者,还有另外一退出方式,是os._exit(),这两个有所区别。

#!/usr/bin/env python
# coding=utf-8

import sys

for i in range(10):
    if i == 5:
        sys.exit()
    else:
        print i        #Python 3: print(i)

这段程序的运行结果就是:

$ python 22102.py
0
1
2
3
4

在大多数函数中会用到return,其含义是终止当前的函数,并向调用函数的位置返回相应值(如果没有就是None)。但是sys.exit()的含义是退出当前程序——不仅仅是函数,并发起SystemExit异常。这就是两者的区别了。

如果使用sys.exit(0)表示正常退出。若需要在退出的时候有一个对人友好的提示,可以用sys.exit("I wet out at here."),那么字符串信息就被打印出来。

sys.path

sys.path已经不陌生了,它可以查找模块所在的目录,以列表的形式显示出来。如果用append()方法,就能够向这个列表增加新的模块目录。如前所演示。不在赘述。

sys.stdout

sys.stdinsys.stdoutsys.stderr这三个有相似之处,它们所实现的都是类文件流,分别表示标准UNIX概念中的标准输入、标准输出和标准错误。

与Python中的函数功能对照,sys.stdin获得输入(等价于Python 2中的raw_input(),Python 3中的input()),sys.stdout负责输出。

流是程序输入或输出的一个连续的字节序列,设备(例如鼠标、键盘、磁盘、屏幕、调制解调器和打印机)的输入和输出都是用流来处理的。程序在任何时候都可以使用它们。一般来讲,stdin(输入)并不一定来自键盘,stdout(输出)也并不一定显示在屏幕上,它们都可以重定向到磁盘文件或其它设备上。

此处仅就sys.stdout做一个简要说明。

>>> for i in range(3):
...     print i        #Python 3: print(i)
... 
0
1
2

print语句或者函数,你一定很熟悉,此前用的很多。并且,特别说明,在默认情况下,不管是语句还是函数,最后都是有\n换行的。这种输入,本质上是用sys.stdout.write(object + '\n')实现。

>>> import sys
>>> for i in range(3):
...     sys.stdout.write(str(i))
... 
012>>> 

跟前面的不同,是因为没有加上那个\n

>>> for i in range(3):
...     sys.stdout.write(str(i) + '\n')
... 
0
1
2

从这看出,两者是完全等效的。如果仅仅止于此,意义不大。关键是通过sys.stdout能够做到将输出内容从“控制台”转到“文件”,称之为重定向。这样也许控制台看不到(很多时候这个不重要),但是文件中已经有了输出内容。比如:

>>> f = open("stdout.md", "w")
>>> sys.stdout = f
>>> print "Learn Python: From Beginner to Master"        #Python 3: print("Learn Python: From Beginner to Master")
>>> f.close()

sys.stdout = f之后,就意味着将输出目的地转到了打开(建立)的文件中,如果使用print,即将内容输出到这个文件中,在控制台并无显现。

打开文件看看便知:

$ cat stdout.md
Learn Python: From Beginner to Master

以上,对标准库中的sys有了粗浅的了解。更详细内容,请读者运用本书已经反复使用的dir()help()去探究,当然还有Google。

copy

前面对浅拷贝和深拷贝做了研究,这里再次提出,温故知新。

>>> import copy
>>> copy.__all__
['Error', 'copy', 'deepcopy']

这个模块中常用的就是copy和deepcopy。

为了具体说明,看这样一个例子,这个例子跟以前讨论浅拷贝和深拷贝略有不同,请读者认真推敲结果,并对照代码。

#!/usr/bin/env python
# coding=utf-8

import copy

class MyCopy(object):    #Python 3: class MyCopy:
    def __init__(self, value):
        self.value = value

    def __repr__(self):
        return str(self.value)

foo = MyCopy(7)

a = ["foo", foo]
b = a[:]
c = list(a)
d = copy.copy(a)
e = copy.deepcopy(a)

a.append("abc")
foo.value = 17

print "original: {0}\n slice: {1}\n list(): {2}\n copy(): {3}\n deepcopy(): {4}\n".forrmat(a,b,c,d,e)
#Python 3:
#print("original: {0}\n slice: {1}\n list(): {2}\n copy(): {3}\n deepcopy(): {4}\n".format(a,b,c,d,e))

保存并运行:

$ python 22103.py 
original: ['foo', 17, 'abc']
 slice: ['foo', 17]
 list(): ['foo', 17]
 copy(): ['foo', 17]
 deepcopy(): ['foo', 7]

尽在不言中,请读者认真对照上面的显示结果,体会深拷贝和浅拷贝。


总目录   |   上节:标准库(1)   |   下节:标准库(3)

如果你认为有必要打赏我,请通过支付宝:[email protected],不胜感激。

results matching ""

    No results matching ""