Python标准库

Python标准库

文章目录

  • Python标准库
  • 1. 核心模块
    • 1.1. 介绍
      • 1.1.1. 内建函数和异常
      • 1.1.2. 操作系统接口模块
      • 1.1.3. 类型支持模块
      • 1.1.4. 正则表达式
      • 1.1.5. 语言支持模块
    • 1.2. _ _builtin_ _ 模块
      • 1.2.1. 使用元组或字典中的参数调用函数
      • 1.2.2. 加载和重载模块
      • 1.2.3. 关于名称空间
      • 1.2.4. 检查对象类型
      • 1.2.5. 计算 Python 表达式
      • 1.2.6. 编译和执行代码
      • 1.2.7. 从 _ _builtin_ _ 模块重载函数
    • 1.3. exceptions 模块
    • 1.4. os 模块
      • 1.4.1. 处理文件
      • 1.4.2. 处理目录
      • 1.4.3. 处理文件属性
      • 1.4.4. 处理进程
      • 1.4.5. 处理守护进程(Daemon Processes)
    • 1.5. os.path 模块
      • 1.5.1. 处理文件名
      • 1.5.2. 搜索文件系统
    • 1.6. stat 模块
    • 1.7. string 模块
    • 1.8. re 模块
    • 1.9. math 模块
    • 1.10. cmath 模块
    • 1.11. operator 模块
    • 1.12. copy 模块
    • 1.13. sys 模块
      • 1.13.1. 处理命令行参数
      • 1.13.2. 处理模块
      • 1.13.3. 处理引用记数
      • 1.13.4. 跟踪程序
      • 1.13.5. 处理标准输出/输入
      • 1.13.6. 退出程序
    • 1.14. atexit 模块
    • 1.15. time 模块
      • 1.15.1. 获得当前时间
      • 1.15.2. 将时间值转换为字符串
      • 1.15.3. 将字符串转换为时间对象
      • 1.15.4. 转换时间值
      • 1.15.5. Timing 相关
    • 1.16. types 模块
    • 1.17. gc 模块
  • 2. 更多标准模块
    • 2.1. 概览
      • 2.1.1. 文件与流
      • 2.1.2. 类型封装
      • 2.1.3. 随机数字
      • 2.1.4. 加密算法
    • 2.2. fileinput 模块
    • 2.3. shutil 模块
    • 2.4. tempfile 模块
    • 2.5. StringIO 模块
    • 2.6. cStringIO 模块
    • 2.7. mmap 模块
    • 2.8. UserDict 模块
    • 2.9. UserList 模块
    • 2.10. UserString 模块
    • 2.11. traceback 模块
    • 2.12. errno 模块
    • 2.13. getopt 模块
    • 2.14. getpass 模块
    • 2.15. glob 模块
    • 2.16. fnmatch 模块
    • 2.17. random 模块
    • 2.18. whrandom 模块
    • 2.19. md5 模块
    • 2.20. sha 模块
    • 2.21. crypt 模块
    • 2.22. rotor 模块
    • 2.23. zlib 模块
    • 2.24. code 模块
  • 3. 线程和进程
    • 3.1. 概览
      • 3.1.1. 线程
      • 3.1.2. 进程
    • 3.2. threading 模块
    • 3.3. Queue 模块
    • 3.4. thread 模块
    • 3.5. commands 模块
    • 3.6. pipes 模块
    • 3.7. popen2 模块
    • 3.8. signal 模块
  • 4. 数据表示
    • 4.1. 概览
      • 4.1.1. 二进制数据
      • 4.1.2. 自描述格式
      • 4.1.3. 输出格式
      • 4.1.4. 编码二进制数据
    • 4.2. array 模块
    • 4.3. struct 模块
    • 4.4. xdrlib 模块
    • 4.5. marshal 模块
    • 4.6. pickle 模块
    • 4.7. cPickle 模块
    • 4.8. copy_reg 模块
    • 4.9. pprint 模块
    • 4.10. repr 模块
    • 4.11. base64 模块
    • 4.12. binhex 模块
    • 4.13. quopri 模块
    • 4.14. uu 模块
    • 4.15. binascii 模块
  • 5. 文件格式
    • 5.1. 概览
      • 5.1.1. Markup 语言
      • 5.1.2. 配置文件
      • 5.1.3. 压缩档案格式
    • 5.2. xmllib 模块
    • 5.3. xml.parsers.expat 模块
    • 5.4. sgmllib 模块
    • 5.5. htmllib 模块
    • 5.6. htmlentitydefs 模块
    • 5.7. formatter 模块
    • 5.8. ConfigParser 模块
    • 5.9. netrc 模块
    • 5.10. shlex 模块
    • 5.11. zipfile 模块
      • 5.11.1. 列出内容
      • 5.11.2. 从 ZIP 文件中读取数据
      • 5.11.3. 向 ZIP 文件写入数据
    • 5.12. gzip 模块
  • 6. 邮件和新闻消息处理
    • 6.1. 概览
    • 6.2. rfc822 模块
    • 6.3. mimetools 模块
    • 6.4. MimeWriter 模块
    • 6.5. mailbox 模块
    • 6.6. mailcap 模块
    • 6.7. mimetypes 模块
    • 6.8. packmail 模块
    • 6.9. mimify 模块
    • 6.10. multifile 模块
  • 7. 网络协议
    • 7.1. 概览
      • 7.1.1. Internet 时间协议
      • 7.1.2. HTTP 协议
    • 7.2. socket 模块
    • 7.3. select 模块
    • 7.4. asyncore 模块
    • 7.5. asynchat 模块
    • 7.6. urllib 模块
    • 7.7. urlparse 模块
    • 7.8. cookie 模块
    • 7.9. robotparser 模块
    • 7.10. ftplib 模块
    • 7.11. gopherlib 模块
    • 7.12. httplib 模块
      • 7.12.1. 将数据发送给服务器
    • 7.13. poplib 模块
    • 7.14. imaplib 模块
    • 7.15. smtplib 模块
    • 7.16. telnetlib 模块
    • 7.17. nntplib 模块
      • 7.17.1. 列出消息
      • 7.17.2. 下载消息
    • 7.18. SocketServer 模块
    • 7.19. BaseHTTPServer 模块
    • 7.20. SimpleHTTPServer 模块
    • 7.21. CGIHTTPServer 模块
    • 7.22. cgi 模块
    • 7.23. webbrowser 模块
  • 8. 国际化
    • 8.1. locale 模块
    • 8.2. unicodedata 模块
    • 8.3. ucnhash 模块
  • 9. 多媒体相关模块
    • 9.1. 概览
    • 9.2. imghdr 模块
    • 9.3. sndhdr 模块
    • 9.4. whatsound 模块
    • 9.5. aifc 模块
    • 9.6. sunau 模块
    • 9.7. sunaudio 模块
    • 9.8. wave 模块
    • 9.9. audiodev 模块
    • 9.10. winsound 模块
  • 10. 数据储存
    • 10.1. 概览
    • 10.2. anydbm 模块
    • 10.3. whichdb 模块
    • 10.4. shelve 模块
    • 10.5. dbhash 模块
    • 10.6. dbm 模块
    • 10.7. dumbdbm 模块
    • 10.8. gdbm 模块
  • 11. 工具和实用程序
    • 11.1. dis 模块
    • 11.2. pdb 模块
    • 11.3. bdb 模块

1. 核心模块

“Since the functions in the C runtime library are not part of the Win32 API, we believe the number of applications that will be affected by this bug to be very limited.”

- Microsoft, January 1999


1.1. 介绍

Python 的标准库包括了很多的模块, 从 Python 语言自身特定的类型和声明, 到一些只用于少数程序的不著名的模块.

本章描述了一些基本的标准库模块. 任何大型 Python 程序都有可能直接或间接地使用到这类模块的大部分.

1.1.1. 内建函数和异常

下面的这两个模块比其他模块加在一起还要重要: 定义内建函数(例如 len, int, range …)的 _ _builtin_ _ 模块, 以及定义所有内建异常的exceptions 模块.

Python 在启动时导入这两个模块, 使任何程序都能够使用它们.

1.1.2. 操作系统接口模块

Python 有许多使用了 POSIX 标准 API 和标准 C 语言库的模块. 它们为底层操作系统提供了平台独立的接口.

这类的模块包括: 提供文件和进程处理功能的 os 模块; 提供平台独立的文件名处理(分拆目录名, 文件名, 后缀等)的 os.path模块; 以及时间日期处理相关的 time/datetime 模块.

[!Feather注: datetime 为 Py2.3 新增模块, 提供增强的时间处理方法 ]

延伸一点说, 网络和线程模块同样也可以归为这一个类型. 不过 Python 并没有在所有的平台/版本实现这些.

1.1.3. 类型支持模块

标准库里有许多用于支持内建类型操作的库. string 模块实现了常用的字符串处理. math 模块提供了数学计算操作和常量(pi, e都属于这类常量),cmath 模块为复数提供了和 math 一样的功能.

1.1.4. 正则表达式

re 模块为 Python 提供了正则表达式支持. 正则表达式是用于匹配字符串或特定子字符串的有特定语法的字符串模式.

1.1.5. 语言支持模块

sys 模块可以让你访问解释器相关参数,比如模块搜索路径,解释器版本号等. operator 模块提供了和内建操作符作用相同的函数.copy 模块允许你复制对象, Python 2.0 新加入的 gc 模块提供了对垃圾收集的相关控制功能.


1.2. _ builtin _ 模块

这个模块包含 Python 中使用的内建函数. 一般不用手动导入这个模块; Python会帮你做好一切.

1.2.1. 使用元组或字典中的参数调用函数

Python允许你实时地创建函数参数列表. 只要把所有的参数放入一个元组中,然后通过内建的 apply 函数调用函数. 如 Example 1-1.

1.2.1.1. Example 1-1. 使用 apply 函数

File: builtin-apply-example-1.py

def function(a, b):
    print( a, b)

apply(function, ("whither", "canada?"))
apply(function, (1, 2 + 3))

whither canada?
1 5

要想把关键字参数传递给一个函数, 你可以将一个字典作为 apply 函数的第 3 个参数, 参考 Example 1-2.

1.2.1.2. Example 1-2. 使用 apply 函数传递关键字参数

File: builtin-apply-example-2.py

def function(a, b):
    print( a, b)

apply(function, ("crunchy", "frog"))
apply(function, ("crunchy",), {"b": "frog"})
apply(function, (), {"a": "crunchy", "b": "frog"})

crunchy frog
crunchy frog
crunchy frog

apply 函数的一个常见用法是把构造函数参数从子类传递到基类, 尤其是构造函数需要接受很多参数的时候. 如 Example 1-3 所示.

1.2.1.3. Example 1-3. 使用 apply 函数调用基类的构造函数

File: builtin-apply-example-3.py

class Rectangle:
    def _ _init_ _(self, color="white", width=10, height=10):
        print( "create a", color, self, "sized", width, "x", height)

class RoundedRectangle(Rectangle):
    def _ _init_ _(self, **kw):
        apply(Rectangle._ _init_ _, (self,), kw)

rect = Rectangle(color="green", height=100, width=100)
rect = RoundedRectangle(color="blue", height=20)

create a green  sized 100 x 100
create a blue  sized 10 x 20

Python 2.0 提供了另个方法来做相同的事. 你只需要使用一个传统的函数调用 , 使用 * 来标记元组, ** 来标记字典.

下面两个语句是等价的:

result = function(*args, **kwargs)
result = apply(function, args, kwargs)

1.2.2. 加载和重载模块

如果你写过较庞大的 Python 程序, 那么你就应该知道 import 语句是用来导入外部模块的 (当然也可以使用 from-import版本). 不过你可能不知道 import 其实是靠调用内建函数 _ _import_ _ 来工作的.

通过这个戏法你可以动态地调用函数. 当你只知道模块名称(字符串)的时候, 这将很方便. Example 1-4 展示了这种用法, 动态地导入所有以 “-plugin” 结尾的模块.

1.2.2.1. Example 1-4. 使用 _ import _ 函数加载模块

File: builtin-import-example-1.py

import glob, os

modules = []

for module_file in glob.glob("*-plugin.py"):
    try:
        module_name, ext = os.path.splitext(os.path.basename(module_file))
        module = _ _import_ _(module_name)
        modules.append(module)
    except ImportError:
        pass # ignore broken modules

# say hello to all modules
for module in modules:
    module.hello()

example-plugin says hello

注意这个 plug-in 模块文件名中有个 “-” (hyphens). 这意味着你不能使用普通的 import 命令, 因为 Python 的辨识符不允许有 “-” .

Example 1-5 展示了 Example 1-4 中使用的 plug-in .

1.2.2.2. Example 1-5. Plug-in 例子

File: example-plugin.py

def hello():
    print( "example-plugin says hello")

Example 1-6 展示了如何根据给定模块名和函数名获得想要的函数对象.

1.2.2.3. Example 1-6. 使用 _ import _ 函数获得特定函数

File: builtin-import-example-2.py

def getfunctionbyname(module_name, function_name):
    module = _ _import_ _(module_name)
    return getattr(module, function_name)

print repr(getfunctionbyname("dumbdbm", "open"))


你也可以使用这个函数实现延迟化的模块导入 (lazy module loading). 例如在 Example 1-7 中的 string 模块只在第一次使用的时候导入.

1.2.2.4. Example 1-7. 使用 _ import _ 函数实现 延迟导入

File: builtin-import-example-3.py

class LazyImport:
    def _ _init_ _(self, module_name):
        self.module_name = module_name
        self.module = None
    def _ _getattr_ _(self, name):
        if self.module is None:
            self.module = _ _import_ _(self.module_name)
        return getattr(self.module, name)

string = LazyImport("string")

print string.lowercase

abcdefghijklmnopqrstuvwxyz

Python 也提供了重新加载已加载模块的基本支持. [Example 1-8 #eg-1-8 会加载 3 次 hello.py 文件.

1.2.2.5. Example 1-8. 使用 reload 函数

File: builtin-reload-example-1.py

import hello
reload(hello)
reload(hello)

hello again, and welcome to the show
hello again, and welcome to the show
hello again, and welcome to the show

reload 直接接受模块作为参数.

[!Feather 注:  ^ 原句无法理解, 稍后讨论.]

注意,当你重加载模块时, 它会被重新编译, 新的模块会代替模块字典里的老模块. 但是, 已经用原模块里的类建立的实例仍然使用的是老模块(不会被更新).

同样地, 使用 from-import 直接创建的到模块内容的引用也是不会被更新的.

1.2.3. 关于名称空间

dir 返回由给定模块, 类, 实例, 或其他类型的所有成员组成的列表. 这可能在交互式 Python 解释器下很有用, 也可以用在其他地方.Example 1-9展示了 dir 函数的用法.

1.2.3.1. Example 1-9. 使用 dir 函数

File: builtin-dir-example-1.py

def dump(value):
    print( value, "=>", dir(value))

import sys

dump(0)
dump(1.0)
dump(0.0j) # complex number
dump([]) # list
dump({}) # dictionary
dump("string")
dump(len) # function
dump(sys) # module

0 => []
1.0 => []
0j => ['conjugate', 'imag', 'real']
[] => ['append', 'count', 'extend', 'index', 'insert',
    'pop', 'remove', 'reverse', 'sort']
{} => ['clear', 'copy', 'get', 'has_key', 'items',
    'keys', 'update', 'values']
string => []
 => ['_ _doc_ _', '_ _name_ _', '_ _self_ _']
 => ['_ _doc_ _', '_ _name_ _',
    '_ _stderr_ _', '_ _stdin_ _', '_ _stdout_ _', 'argv',
    'builtin_module_names', 'copyright', 'dllhandle',
    'exc_info', 'exc_type', 'exec_prefix', 'executable',
...

在例子 Example 1-10中定义的 getmember 函数返回给定类定义的所有类级别的属性和方法.

1.2.3.2. Example 1-10. 使用 dir 函数查找类的所有成员

File: builtin-dir-example-2.py

class A:
    def a(self):
        pass
    def b(self):
        pass

class B(A):
    def c(self):
        pass
    def d(self):
        pass

def getmembers(klass, members=None):
    # get a list of all class members, ordered by class
    if members is None:
        members = []
    for k in klass._ _bases_ _:
        getmembers(k, members)
    for m in dir(klass):
        if m not in members:
            members.append(m)
    return members

print getmembers(A)
print getmembers(B)
print getmembers(IOError)

['_ _doc_ _', '_ _module_ _', 'a', 'b']
['_ _doc_ _', '_ _module_ _', 'a', 'b', 'c', 'd']
['_ _doc_ _', '_ _getitem_ _', '_ _init_ _', '_ _module_ _', '_ _str_ _']

getmembers 函数返回了一个有序列表. 成员在列表中名称出现的越早, 它所处的类层次就越高. 如果无所谓顺序的话, 你可以使用字典代替列表.

[!Feather 注: 字典是无序的, 而列表和元组是有序的, 网上有关于有序字典的讨论]

vars 函数与此相似, 它返回的是包含每个成员当前值的字典. 如果你使用不带参数的 vars , 它将返回当前局部名称空间的可见元素(同locals() 函数 ). 如 Example 1-11所表示.

1.2.3.3. Example 1-11. 使用 vars 函数

File: builtin-vars-example-1.py

book = "library2"
pages = 250
scripts = 350


print "the %(book)s book contains more than %(scripts)s scripts" % vars()

the library book contains more than 350 scripts

1.2.4. 检查对象类型

Python 是一种动态类型语言, 这意味着给一个定变量名可以在不同的场合绑定到不同的类型上. 在接下面例子中, 同样的函数分别被整数, 浮点数, 以及一个字符串调用:

def function(value):
    print( value)
function(1)
function(1.0)
function("one")

type 函数 (如 Example 1-12 所示) 允许你检查一个变量的类型. 这个函数会返回一个type descriptor (类型描述符), 它对于 Python 解释器提供的每个类型都是不同的.

1.2.4.1. Example 1-12. 使用 type 函数

File: builtin-type-example-1.py

def dump(value):
    print( type(value), value)

dump(1)
dump(1.0)
dump("one")

 1
 1.0
 one

每个类型都有一个对应的类型对象, 所以你可以使用 is 操作符 (对象身份?) 来检查类型. (如 Example 1-13所示).

1.2.4.2. Example 1-13. 对文件名和文件对象使用 type 函数

File: builtin-type-example-2.py

def load(file):
    if isinstance(file, type("")):
        file = open(file, "rb")
    return file.read()

print len(load("samples/sample.jpg")), "bytes"
print len(load(open("samples/sample.jpg", "rb"))), "bytes"


4672 bytes
4672 bytes

callable 函数, 如 Example 1-14 所示, 可以检查一个对象是否是可调用的 (无论是直接调用或是通过apply). 对于函数, 方法, lambda 函式, 类, 以及实现了 _ _call_ _ 方法的类实例, 它都返回 True.

1.2.4.3. Example 1-14. 使用 callable 函数

File: builtin-callable-example-1.py

def dump(function):
    if callable(function):
        print( function, "is callable")
    else:
        print( function, "is *not* callable")

class A:
    def method(self, value):
        return value

class B(A):
    def _ _call_ _(self, value):
        return value

a = A()
b = B()

dump(0) # simple objects
dump("string")
dump(callable)
dump(dump) # function

dump(A) # classes
dump(B)
dump(B.method)

dump(a) # instances
dump(b)
dump(b.method)

0 is *not* callable
string is *not* callable
 is callable
 is callable
A is callable
B is callable
 is callable
 is *not* callable
 is callable
 is callable

注意类对象 (A 和 B) 都是可调用的; 如果调用它们, 就产生新的对象(类实例). 但是 A 类的实例不可调用, 因为它的类没有实现 _ _call_ _ 方法.

你可以在 operator 模块中找到检查对象是否为某一内建类型(数字, 序列, 或者字典等)的函数. 但是, 因为创建一个类很简单(比如实现基本序列方法的类), 所以对这些类型使用显式的类型判断并不是好主意.

在处理类和实例的时候会复杂些. Python 不会把类作为本质上的类型对待; 相反地, 所有的类都属于一个特殊的类类型(special class type), 所有的类实例属于一个特殊的实例类型(special instance type).

这意味着你不能使用 type 函数来测试一个实例是否属于一个给定的类; 所有的实例都是同样的类型! 为了解决这个问题, 你可以使用isinstance 函数,它会检查一个对象是不是给定类(或其子类)的实例. Example 1-15 展示了 isinstance 函数的使用.

1.2.4.4. Example 1-15. 使用 isinstance 函数

File: builtin-isinstance-example-1.py

class A:
    pass

class B:
    pass

class C(A):
    pass

class D(A, B):
    pass

def dump(object):
    print( object, "=>",)
    if isinstance(object, A):
        print( "A",)
    if isinstance(object, B):
        print( "B",)
    if isinstance(object, C):
        print( "C",)
    if isinstance(object, D):
        print( "D",)
    print()

a = A()
b = B()
c = C()
d = D()

dump(a)
dump(b)
dump(c)
dump(d)
dump(0)
dump("string")

 => A
 => B
 => A C
 => A B D
0 =>
string =>

issubclass 函数与此相似, 它用于检查一个类对象是否与给定类相同, 或者是给定类的子类. 如 Example 1-16 所示.

注意, isinstance 可以接受任何对象作为参数, 而 issubclass 函数在接受非类对象参数时会引发TypeError 异常.

1.2.4.5. Example 1-16. 使用 issubclass 函数

File: builtin-issubclass-example-1.py

class A:
    pass

class B:
    pass

class C(A):
    pass

class D(A, B):
    pass

def dump(object):
    print( object, "=>",)
    if issubclass(object, A):
        print( "A",)
    if issubclass(object, B):
        print( "B",)
    if issubclass(object, C):
        print( "C",)
    if issubclass(object, D):
        print( "D",)
    print()

dump(A)
dump(B)
dump(C)
dump(D)
dump(0)
dump("string")

A => A
B => B
C => A C
D => A B D
0 =>
Traceback (innermost last):
  File "builtin-issubclass-example-1.py", line 29, in ?
  File "builtin-issubclass-example-1.py", line 15, in dump
TypeError: arguments must be classes

1.2.5. 计算 Python 表达式

Python 提供了在程序中与解释器交互的多种方法. 例如 eval 函数将一个字符串作为 Python 表达式求值. 你可以传递一串文本, 简单的表达式, 或者使用内建 Python 函数. 如Example 1-17 所示.

1.2.5.1. Example 1-17. 使用 eval 函数

File: builtin-eval-example-1.py

def dump(expression):
    result = eval(expression)
    print( expression, "=>", result, type(result))

dump("1")
dump("1.0")
dump("'string'")
dump("1.0 + 2.0")
dump("'*' * 10")
dump("len('world')")

1 => 1 
1.0 => 1.0 
'string' => string 
1.0 + 2.0 => 3.0 
'*' * 10 => ********** 
len('world') => 5 

如果你不确定字符串来源的安全性, 那么你在使用 eval 的时候会遇到些麻烦. 例如, 某个用户可能会使用 _ _import_ _ 函数加载os 模块, 然后从硬盘删除文件 (如 Example 1-18 所示).

1.2.5.2. Example 1-18. 使用 eval 函数执行任意命令

File: builtin-eval-example-2.py

print eval("_ _import_ _('os').getcwd()")
print eval("_ _import_ _('os').remove('file')")

/home/fredrik/librarybook
Traceback (innermost last):
 File "builtin-eval-example-2", line 2, in ?
 File "", line 0, in ?
os.error: (2, 'No such file or directory')

这里我们得到了一个 os.error 异常, 这说明 Python 事实上在尝试删除文件!

幸运地是, 这个问题很容易解决. 你可以给 eval 函数传递第 2 个参数, 一个定义了该表达式求值时名称空间的字典. 我们测试下, 给函数传递个空字典:

>>> print( eval("_ _import_ _('os').remove('file')", {}))
Traceback (innermost last):
  File "", line 1, in ?
  File "", line 0, in ?
os.error: (2, 'No such file or directory')

呃… 我们还是得到了个 os.error 异常.

这是因为 Python 在求值前会检查这个字典, 如果没有发现名称为 _ _builtins_ _ 的变量(复数形式), 它就会添加一个:

>>> namespace = {}
>>> print( eval("_ _import_ _('os').remove('file')", namespace))
Traceback (innermost last):
  File "", line 1, in ?
  File "", line 0, in ?
os.error: (2, 'No such file or directory')
>>> namespace.keys()
['_ _builtins_ _']

如果你打印这个 namespace 的内容, 你会发现里边有所有的内建函数.

[!Feather 注: 如果我RP不错的话, 添加的这个_ _builtins_ _就是当前的_ _builtins_ _]

我们注意到了如果这个变量存在, Python 就不会去添加默认的, 那么我们的解决方法也来了, 为传递的字典参数加入一个 _ _builtins_ _ 项即可. 如Example 1-19 所示.

1.2.5.3. Example 1-19. 安全地使用 eval 函数求值

File: builtin-eval-example-3.py

print eval("_ _import_ _('os').getcwd()", {})
print eval("_ _import_ _('os').remove('file')", {"_ _builtins_ _": {}})

/home/fredrik/librarybook
Traceback (innermost last):
  File "builtin-eval-example-3.py", line 2, in ?
  File "", line 0, in ?
NameError: _ _import_ _

即使这样, 你仍然无法避免针对 CPU 和内存资源的攻击. (比如, 形如 eval("'*'*1000000*2*2*2*2*2*2*2*2*2") 的语句在执行后会使你的程序耗尽系统资源).

1.2.6. 编译和执行代码

eval 函数只针对简单的表达式. 如果要处理大块的代码, 你应该使用 compileexec 函数 (如 Example 1-20 所示).

1.2.6.1. Example 1-20. 使用 compile 函数检查语法

File: builtin-compile-example-1.py

NAME = "script.py"

BODY = """
prnt 'owl-stretching time'
"""

try:
    compile(BODY, NAME, "exec")
except SyntaxError, v:
    print( "syntax error:", v, "in", NAME)

# syntax error: invalid syntax in script.py

成功执行后, compile 函数会返回一个代码对象, 你可以使用 exec 语句执行它, 参见 Example 1-21 .

1.2.6.2. Example 1-21. 执行已编译的代码

File: builtin-compile-example-2.py

BODY = """
print 'the ant, an introduction'
"""

code = compile(BODY, "
                    
                    

你可能感兴趣的:(python从入门到精通,Python,python)