• python学习笔记15执行环境


    可调用对象
    代码对象


    一、可调用对象
    Python 有4 种可调用对象:函数,方法,类,以及一些类的实例。记住这些对象的任何引用或者别名都是可调用的。
    1、函数
    python 有3 种不同类型函数对象。第一种是内建函数。
    1)内建函数(BIFs)
    这些函数在_bulitin_模块里,并作为__builtins__块导入到解释器中。
    内建函数属性
    BIF 属性 描述
    bif.__doc__ 文档字符串(或None)
    bif.__name__ 字符串类型的文档名字
    bif.__self__ 设置为None(保留给built-in 方法)
    bif.__module__ 存放bif 定义的模块名字(或None)
    2)用户定义的函数(UDF)
    UDF(User-DefinedFunction,用户定义的函数)通常是用python写的,定义在模块的最高级,因此会作为全局名字空间的一部分(一旦创建好内建名字空间)装载到系统中。函数也可在
    其他的函数体内定义.
    用户自定义函数属性
    UDF 属性 描述
    udf.__doc__ 文档字符串(也可以用udf.func_doc)
    udf.__name__ 字符串类型的函数名字(也可以用 udf.func_name)
    udf.func_code 字节编译的代码对象
    udf.func_defaults 默认的参数元组
    udf.func_globals 全局名字空间字典; 和从函数内部调用globals(x)一样
    udf.func_dict 函数属性的名字空间
    udf.func_doc (见上面的udf.__doc__)
    udf.func_name (见上面的udf.__name__)
    udf.func_closure 包含了自由变量的引用的单元对象元组(自用变量在UDF 中使用,但在别处定义;参见python[语言]参考手册)
    3)方法
    用户自定义方法是被定义为类的一部分的函数。许多python 数据类型,比如列表和字典,也有方法,这些被称为内建方法。
    内建方法(BIM)属性
    BIM 属性 描述
    bim.__doc__ 文档字串
    bim.__name__ 字符串类型的函数名字
    bim.__self__ 绑定的对象
    内建方法(BIMs)
    BIM 和BIF 两者也都享有相同属性。不同之处在于BIM 的__self__属性指向一个Python对象,而BIF 指向None。
    用户定义的方法(UDM)
    UDM(User-defined method,用户定义的方法)包含在类定义之中,只是拥有标准函数的包装,
    仅有定义它们的类可以使用。如果没有在子类定义中被覆盖掉,也可以通过子类实例来调用它们。

    2、方法
    1)、内建方法(BIM)属性
    BIM 属性 描述
    bim.__doc__ 文档字串
    bim.__name__ 字符串类型的函数名字
    bim.__self__ 绑定的对象
    内建方法与内建函数的类似之处。只有内建类型(BIT)有BIM.正如
    你在下面看到的,对于内建方法,type()工厂函数给出了和BIF 相同的输出--注意,
    >>> type([].append)
    <type 'builtin_function_or_method'>
    此外,BIM 和BIF 两者也都享有相同属性。不同之处在于BIM 的__self__属性指向一个Python
    对象,而BIF 指向None
    2)、用户定义的方法(UDM)
    UDM(User-definedmethod,用户定义的方法)包含在类定义之中,只是拥有标准函数的包装,仅有定义它们的类可以使用。如果没有在子类定义中被
    覆盖掉,也可以通过子类实例来调用它们。UDM 与类对象是关联的(非绑定方法),但是只能通过类的实例来调用(绑定方法)。无论UDMs 是否绑定,所有的UMD 都是相同的类用户自定义属性
    UDM 属性 描述
    udm.__doc__ 文档字符串(与udm.im_fuc.__doc__相同)
    udm.__name__ 字符串类型的方法名字(与umd.im_func.__name__相同)
    udm.__module__ 定义udm 的模块的名字(或none)
    udm.im_class 方法相关联的类(对于绑定的方法;如果是非绑定,那么为要求udm 的类)型——“实例方法“
    udm.im_func 方法的函数对象(见UDFs)
    udm.im_self 如果绑定的话为相关联的实例,如果非绑定位为none

    3、类
    1)、类的实例
    python 给类提供了名为__call__的特别方法,该方法允许程序员创建可调用的对象(实例)。默
    认情况下,__call__()方法是没有实现的,这意味着大多数实例都是不可调用的。然而,如果在类
    定义中覆盖了这个方法,那么这个类的实例就成为可调用的了。调用这样的实例对象等同于调用
    __call__()方法。自然地,任何在实例调用中给出的参数都会被传入到__call()__中。……那么foo()
    就和foo.__call__(foo)的效果相同, 这里foo 也作为参数出现,因为是对自己的引用,实例将自
    动成为每次方法调用的第一个参数。如果 ___call___()有参数,比如,(self, arg),那么foo(arg)
    就和调用foo.__call__(foo, arg)一样。
    正常情况是通过实例调用类的方法。直接调用调用实例,需要类中定义__call__()方法。

    __call__拦截调用:如果定义了,Python就会为实例应用函数调用表达式运行__call__方法。
    当需要为函数的API编写接口时,__call__就变得很用有:这可以编写遵循所需要的函数来调用接口对象。
    函数接口和回调代码

    二、代码对象
    可调用的对象是python 执行环境里最重要的部分,然而他们只是冰山一角。python 语句,赋值,
    表达式,甚至还有模块构成了更宏大的场面。这些可执行对象无法像可调用物那样被调用。更确切
    地说,这些对象只是构成可执行代码块的拼图的很小一部分,而这些代码块被称为代码对象。
    每个可调用物的核心都是代码对象,由语句,赋值,表达式,以及其他可调用物组成。察看一
    个模块意味着观察一个较大的、包含了模块中所有代码的对象。然后代码可以分成语句,赋值,表
    达式,以及可调用物。可调用物又可以递归分解到下一层,那儿有自己的代码对象。

    【一般说来,代码对象可以作为函数或者方法调用的一部分来执行,也可用exec 语句或内建函数eval()来执行。】
    从整体上看,一个python 模块的代码对象是构成该模块的全部代码。

    如果要执行python 代码,那么该代码必须先要转换成字节编译的代码(又称字节码)。这才是
    真正的代码对象。然而,它们不包含任何关于它们执行环境的信息,这便是可调用物存在的原因,
    它被用来包装一个代码对象并提供额外的信息。

    UDF 的udf.func_code 属性吗?那就是代码对象。

    三、可执行的对象声明和内建函数
    Python 提供了大量的BIF 来支持可调用/可执行对象,其中包括exec 语句。这些函数帮助程序员执行代码对象,也可以用内建函数complie()来生成代码对象。
    可执行对象和内建函数

    内建函数和语句 描述
    callable(obj) 如果obj可调用,返回True,否则返回FALSE
    compile(string,file, type) 从type 类型中创建代码对象;file 是代码存放的地方(通常设为"")
    eval(obj, glo- bals=globals(),locals=locals()) 对obj 进行求值,obj 是已编译为代码对象的表达式,或是一个字符串表达式;可以给出全局或者/和局部的名字空间
    exec obj 执行obj、单一的python 语句或者语句的集合,也就是说格式是代码对象或者字符串;obj 也可以是一个文件对象(已经打开的有效python 脚本中)
    input(prompt='') 等同于eval(raw_input(prompt=”))

    1、callable()
    callable()是一个布尔函数,确定一个对象是否可以通过函数操作符(())来调用。如果函数可
    调用便返回True,否则便是False.

    2、compile()
    compile()函数允许程序员在运行时刻迅速生成代码对象,然后就可以用exec 语句或者内建函
    数eval()来执行这些对象或者对它们进行求值。一个很重要的观点是:exec 和eval()都可以执行字
    符串格式的Python 代码。当执行字符串形式的代码时,每次都必须对这些代码进行字节编译处理。
    compile()函数提供了一次性字节代码预编译,以后每次调用的时候,都不用编译了。

    compile 的三个参数都是必需的,第一参数代表了要编译的python 代码。第二个字符串,虽然是必需的,但通常被置为空串。该参数代表了存放代码对象的文件的名字(字符串类型)。
    compile的通常用法是动态生成字符串形式的Python代码, 然后生成一个代码对象——代码显然没有存放在任何文件。
    最后的参数是个字符串,它用来表明代码对象的类型。有三个可能值:
    'eval' 可求值的表达式[和eval()一起使用]
    'single' 单一可执行语句[和exec 一起使用]
    'exec' 可执行语句组[和exec 一起使用]
    可求值表达式
    >>> eval_code = compile('100 + 200', '', 'eval')
    >>> eval(eval_code)
    300
    单一可执行语句
    >>> single_code = compile('print "Hello world!"', '', 'single')
    >>> single_code
    <code object ? at 120998, file "", line 0>
    >>> exec single_code
    Hello world!
    可执行语句组
    >>> exec_code = compile("""
    ... req = input('Count how many numbers? ')
    ... for eachNum in range(req):
    ... print eachNum
    ... """, '', 'exec')
    >>> exec exec_code
    Count how many numbers? 6
    0
    1
    2
    3
    4
    5
    3、eval()
    eval()对表达式求值,后者可以为字符串或内建函数complie()创建的预编译代码对象。这是
    eval()第一个也是最重要的参数.第二个和第三个参数,都为可选
    的,分别代表了全局和局部名字空间中的对象。如果给出这两个参数,globals 必须是个字典,locals
    可以是任意的映射对象,比如,一个实现了__getitem__()方法的对象。如果都没给出这两个参数,分别默认为globals()和locals()返回的对象,如果只传入
    了一个全局字典,那么该字典也作为locals 传入。
    >>> eval('100 + 200')
    300
    4、exec
    和eval()相似,exec 语句执行代码对象或字符串形式的python 代码。类似地,用compile()
    预编译重复代码有助于改善性能,因为在调用时不必经过字节编译处理。exec 语句只接受一个参数,
    下面便是它的通用语法:
    exec obj
    被执行的对象(obj)可以只是原始的字符串,比如单一语句或是语句组,它们也可以预编译成
    一个代码对象(分别用'single'和'exec"参数)。下面的例子中,多个语句作为一个字符串发送给exec:
    >>> exec """
    ... x = 0
    ... print 'x is currently:', x
    ... while x < 5:
    ... x += 1
    ... print 'incrementing x to:', x
    ... """
    【exec 还可以接受有效的python 文件对象】。如果我们用上面的多行代码创建一个叫
    xcount.py 的文件,那么也可以用下面的方法执行相同的代码
    >>> f = open('xcount.py') # open the file
    >>> exec f # execute the file
    x is currently: 0
    incrementing x to: 1
    incrementing x to: 2
    incrementing x to: 3
    incrementing x to: 4
    incrementing x to: 5
    >>> exec f #尝试再一次执行
    >>> #哦,失败了....为什么?
    5、可执行对象语句和内建函数
    注意一旦执行完毕,继续对exec 的调用就会失败。呃,并不是真正的失败。。。只是不再做任何
    事,这或许让你感到吃惊。事实上,exec 已从文件中读取了全部的数据且停留在文件末尾(EOF)。当
    用相同文件对象对exec 进行调用的时候,便没有可以执行的代码了,所以exec 什么都不做,如同
    上面看见的行为。我们如何知道它在EOF 呢?
    我们用文件对象的tell()方法来告诉我们处于文件的何处,然后用os.path.getsize()来告诉
    我们xcount.py 脚本有多大。这样你就会发现,两个数字完全一样:
    >>> f.tell() # where are we in the file? # 我们在文件的什么地方?
    116
    >>> f.close() # close the file # 关闭文件
    >>> from os.path import getsize
    >>> getsize('xcount.py') # what is the file size? # 文件有多大?
    116
    6、input()
    内建函数input()是eval()和raw_input()的组合,等价于eval(raw_input())。类似于
    raw_input(),input()有一个可选的参数,该参数代表了给用户的字符串提示。如果不给定参数的
    话,该字符串默认为空串。
    从功能上看,input 不同于raw_input(),因为raw_input()总是以字符串的形式,逐字地返回用
    户的输入。input()履行相同的的任务;而且,它还把输入作为python 表达式进行求值。这意味着
    input()返回的数据是对输入表达式求值的结果:一个python 对象。
    下面的例子会让人更加清楚:当用户输入一个列表时,raw_input()返回一个列表的字符串描绘,
    而input()返回实际的列表:
    >>> aString = raw_input('Enter a list: ') Enter a list: [ 123, 'xyz', 45.67 ]
    >>> aString
    "[ 123, 'xyz', 45.67 ]"
    >>> type(aString)
    <type 'str'>
    上面用raw_input()运行。正如你看见的,每样东西都是字符串。现在来看看当用input()的时
    候会发生什么:
    >>> aList = input('Enter a list: ') Enter a list: [ 123, 'xyz', 45.67 ]
    >>> aList
    [123, 'xyz', 45.67]
    >>> type(aList)
    <type 'list'>

    区别raw_input()不会输入求值是什么就是什么(字符串),input()会对输入进行求值,这个值是一个python对象


    四、执行其他程序
    1、导入
    第一次导入模块会执行模块最高级的代码。不管你是否需要,这就是python 导入的行为。提醒,只有属于模块最高级的代码才是全局变量,全局类,和全局函数声明。
    跟着应该是一个if 语句,它通过检测__name__来确定是否要调用脚本,比如,“if__name__ =='__main__'”。如果相等的话,你的脚本会执行main 内代码;否则只是打算导入这个脚本,
    那么可以在这个模块内对代码进行测试。
    2、execfile()
    f = open(filename, 'r')
    exec f f.close()
    这3 行可以调用execfile()来换掉:
    execfile(filename)
    虽然上述代码执行了一个模块,但是仅可以在现有的执行环境下运行(比如,它自己的全局和局部的名字空间)。
    在某些情况下,可能需要用不同全局和局部的名字空间集合,而不是默认的集合来执行模块。execfile() 函数的语法非常类似于eval()函数的。execfile(filename, globals=globals(), locals=locals())
    类似eval(),globals 和locals 都是可选的,如果不提供参数值的话,默认为执行环境的名字空间。
    如果只给定globals,那么locals 默认和globals 相同。如果提供locals 值的话,它可以是任何映射对象[一个定义/覆盖了__getitem__()的对象]。
    3、将模块作为脚本执行
    允许从shell 或DOS 提示符,直接把模块作为脚本来执行。
    $ myScript.py # or $ python myScript.py
    如果模块是标准库的一部分,安装在site-packages 里,或者仅仅是包里面的模块,处理这样
    的模块就不是那么容易了,尤其是它们共享了已存在的同名python 模块。举例来说,你想运行免费
    的python web 服务器,以便创建和测试你自己的web 页面和CGI 脚本。
    你将必须在命令行敲入如下的东西:
    $ python /usr/local/lib/python2x/CGIHTTPServer.py
    Serving HTTP on 0.0.0.0 port 8000 ...
    这是段很长的命令,如果它是第三方的,你不得不深入到site-packages 去找到它真正定位的
    地方。如果没给出完全的路径名,可以从命令行运行一个模块,并让python 的导入机制为我们做这
    种跑腿工作吗?答案是肯定的。我们可以用python -c 命令行开关:
    $ python -c "import CGIHTTPServer; CGIHTTPServer.test()" #作为模块
    该选项允许你指定你想要运行的python 语句。虽然它可以这样工作,但问题是__name__模块不
    是‘__main__’........而是你正在使用的模块。解释器通过import 装载了你的模块,并不是它当作脚本。因为如此,所有
    在if __name__ == '__main__' 之下的代码是不会执行的,所以你不得不手动地调用模块的test()
    函数,就如同前面我们所做的一样。所以我们想同时要两者的优点——能够在类库中执行作为脚本
    的模块而不是作为导入的模块。这就是-m 参数的动机。现在可以像这样运行脚本:
    $ python -m CGIHTTPServer #作为脚本

    五、执行其他非python程序
    1、OS模板
    执行外部程序的os 模块函数
    (u 只对unix 有效, w 只对windows 有效)
    os 模块函数 描述
    system(cmd) 执行程序cmd(字符串),等待程序结束,返回退出代码(windows 下,始终为0)
    fork() 创建一个和父进程并行的子进程[通常来说和exec*()一起使用];返回两次....一次给父进程一次给子进程
    execl(file, arg0,arg1,...) 用参数列表arg0, arg1 等等执行文件
    execv(file, arglist) 除了使用参数向量列表,其他的和execl()相同
    execle(file, arg0,arg1,... env) 和execl 相同,但提供了环境变量字典env
    execve(file,arglist, env) 除了带有参数向量列表,其他的和execle()相同
    execlp(cmd, arg0,arg1,...) 于execl()相同,但是在用户的搜索路径下搜索完全的文件路径名
    execvp(cmd, arglist) 除了带有参数向量列表,与execlp()相同
    execlpe(cmd, arg0, arg1,... env) 和execlp 相同,但提供了环境变量字典env
    execvpe(cmd,arglist, env) 和execvp 相同,但提供了环境变量字典env
    spawn*a(mode, file, args[, env]) spawn*()家族在一个新的进程中执行路径,args 作为参数,也许还有环境变量的字典env;模式(mode)是个显示不同操作模式的魔术。
    wait() 等待子进程完成[通常和fock 和exec*()一起使用] ○U
    waitpid(pid,options) 等待指定的子进程完成[通常和fock 和exec*()一起使用] ○U
    popen(cmd, mode='r',buffering=-1) 执行字符串cmd,返回一个类文件对象作为运行程序通信句柄,默认为读取模式和默认系统缓冲
    startfileb(path) 用关联的应用程序执行路径 W

    a. spawn*()函数命名与exec*()相似(两个家族都有8 个成员);spawnv()和spawnve()在
    python 1.5.2 加入,其他的六个spawn*()函数在python 1.6 加入;spawnlp(), spawnlpe(),
    spawnvp() 和spawnvpe()只适用于unix 平台。

    1)、os.system()
    system(),一个非常简单的函数,接收字符串形式的系统命令并执行它。当执行命令的时候,python 的运行是挂起的。
    当我们的执行完成之后,将会以system()的返回值形式给出退出状态,python 的执行也会继续。
    system()保留了现有的标准文件,包括标准的输出,意味着执行任何的命令和程序显示输出都会传到标准输出上。
    通过退出状态显示成功或失败而不是通过输入
    和/或输出通信。通常的约定是利用退出状态,0 表示成功,非零表示其他类型的错误。
    >>> import os
    >>> result = os.system('cat /etc/motd') Have a lot of fun...
    >>> result
    0
    >>> result = os.system('uname -a')
    Linux solo 2.2.13 #1 Mon Nov 8 15:08:22 CET 1999 i586 unknown
    >>> result
    0
    2)、os.popen()
    popen()函数是文件对象和system()函数的结合。
    它工作方式和system()相同,但它可以建立
    一个指向那个程序的单向连接,然后如访问文件一样访问这个程序。如果程序要求输入,那么你要
    用'w'模式写入那个命令来调用popen()。你发送给程序的数据会通过标准输入接收到。同样地,'r'
    模式允许spawn 命令,那么当它写入标准输出的时候,你就可以通过类文件句柄使用熟悉的file 对
    象的read*()方法来读取输入。就像对于文件,当使用完毕以后,你应当close()连接。
    >>> import os
    >>> f = os.popen('uname -a')
    >>> data = f.readline()
    >>> f.close()
    >>> print data,
    Linux solo 2.2.13 #1 Mon Nov 8 15:08:22 CET 1999 i586 unknown
    3、os.fork(), os.exec*(),os.wait*()
    。调用
    fork()的原始进程称为父进程,而作为该调用结果新创建的进程则称为子进程。当子进程返回的时
    候,其返回值永远是0;当父进程返回时,其返回值永远是子进程的进程标识符(又称进程ID,或PID)
    (这样父进程就可以监控所有的子进程了)PID 也是唯一可以区分他们的方式!我们提到了两个进程
    会在调用fork()后立刻运行。因为代码是相同的,如果没有其他的动作,我们将会看到同样的执行
    结果。而这通常不是我们想要的结果。创建另外一个进程的主要目的是为了运行其他程序,所以我
    们必须在父进程和子进程返回时采取分流措施。正如上面我们所说,它们的PID 是不同的,而这正
    是我们区分它们的方法。
    调用wait()会挂起执行(比如,waits),直到子进程(其他的子进程)正常执行完毕或通过
    信号终止。wait()将会收获子进程,释放所有的资源。如果子进程已经完成,那么wait()只是进行
    些收获的过程。waitpid()具有和wait()相同的的功能,但是多了一个参数PID(指定要等待子进
    程的进程标识符),以及选项(通常是零或用‘OR’组成的可选标志集合)
    4)、os.spawn*()
    函数spawn*()家族和fork,exec*()相似,因为它们在新进程中执行命令;然而,你不需要分
    别调用两个函数来创建进程,并让这个进程执行命令。你只需调用一次spawn*()家族。由于其简单
    性,你放弃了“跟踪”父进程和子进程执行的能力;该模型类似于在线程中启动函数

    2、subprocess
    在python2.3 出来之后,一些关于popen5 模块的工作开始展开。一开始该命名继承了先前
    popen*()函数的传统,但是并没有延续下来,该模块最终被命名为subproess,其中一个类叫Popen,
    集中了我们在这章讨论的大部分面向进程的函数。同样也有名为call()的便捷函数,可以轻易地取代了os.system()
    1)、subprocess.call 取代os.system()
    >>> from subprocess import call
    >>> import os
    >>> res = call(('cat', '/etc/motd'))
    Linux starship 2.4.18-1-686 #4 Sat Nov 29 10:18:26 EST 2003 i686
    GNU/Linux
    >>> res
    0
    不赋值给变量,会返回运行输出和退出状态
    >>> subprocess.call(('uname','-a'))
    Linux pxe-svr.skylog.cn 2.6.32-220.el6.i686 #1 SMP Tue Dec 6 16:15:40 GMT 2011 i686 i686 i386 GNU/Linux
    0
    >>> subprocess.call(('uname',' -a'))
    uname: extra operand ` -a'
    Try `uname --help' for more information.
    1
    >>> s
    2)、subprocess.Popen 取代os.popen()
    创建Popen()实例的语法只比调用os.popen()函数复杂了一点
    >>> from subprocess import Popen, PIPE
    >>> f = Popen(('uname', '-a'), stdout=PIPE).stdout
    >>> data = f.readline()
    >>> f.close()
    >>> print data,
    Linux starship 2.4.18-1-686 #4 Sat Nov 29 10:18:26 EST 2003 i686
    GNU/Linux
    >>> f = Popen('who', stdout=PIPE).stdout
    >>> data = [ eachLine.strip() for eachLine in f ]
    >>> f.close()
    >>> for eachLine in data:
    ... print eachLine
    3)、相关函数
    可以执行上述任务的函数(及其模块)
    文件对象 属性 描述
    os/popen2.popen2() a 执行文件,打开文件,从新创建的运行程序读取(stdout),或者向该程序写(stdin)
    os/popen2.popen3() 执行文件,打开文件,从新创建的运行程序读取(stdout 和stder) ,或者向该程序写(stdin)
    os/popen2.popen4() b 执行文件,打开文件,从新创建的运行程序读取(结合stdout,stdout),或者向该程序写(stdin)
    commands.getoutput() 在子进程中执行文件,以字符串返回所有的输出 U
    subprocess.call() 创建subprocess 的便捷函数。 Popen 等待命令完成,然后返回状态代码;与os.system()类似,但是是较灵活的替代方案

    a. python2.0 版新加入
    b. python2.0 时加入到os 和popen2 模块中
    c. python2.4 时加入

    六、结束执行
    当程序运行完成,所有模块最高级的语句执行完毕后退出,我们便称这是干净的执行。可能有
    很多情况,需要从python 提前退出,比如某种致命错误,或是不满足继续执行的条件的时候。
    1、sys.exit() and SystemExit
    立即退出程序并返回调用程序的主要方式是sys 模块中的exit()函数。sys.exit()的语法为:
    sys.exit(status=0)
    当调用sys.exit()时,就会引发systemExit()异常。除非对异常进行监控(在一个try 语句和
    合适的except 子句中),异常通常是不会被捕捉到或处理的,解释器会用给定的状态参数退出,如
    果没有给出的话,该参数默认为0。System Exit 是唯一不看作错误的异常。它仅仅表示要退出python
    的愿望。
    2、sys.exitfunc()
    sys.exitfunc()默认是不可用的,但你可以改写它以提供额外的功能
    当调用了sys.exit()并
    在解释器退出之前,就会用到这个函数了。这个函数不带任何参数的,所以你创建的函数也应该是
    无参的。
    如果sys.exitfunc 已经被先前定义的exit 函数覆盖了,最好的方法是把这段代码作为你exit()
    函数的一部分来执行。一般说来,exit 函数用于执行某些类型的关闭活动,比如关闭文件和网络连
    接,最好用于完成维护任务,比如释放先前保留的系统资源。
    下面的例子介绍了如何设置exit()函数,如果已经被设置了,则确保执行该函数:
    import sys
    prev_exit_func = getattr(sys, 'exitfunc', None)
    def my_exit_func(old_exit = prev_exit_func):
    # :
    # perform cleanup 进行清理
    # :
    if old_exit is not None and callable(old_exit):
    old_exit()
    sys.exitfunc = my_exit_func
    在清理执行以后,我们执行了老的exit()函数。getattr()调用只是检查了先前的exitfunc()
    是否已经定义。如果没有,那么prev_exit_func 赋值为None,否则, prev_exit_func 变成exit 函数新的别名,然后作为参数传入我们的新exit 函数,my_exit_func。
    对getattr()的调用可以这样写:
    if hasattr(sys, 'exitfunc'):
    prev_exit_func = sys.exitfunc # getattr(sys, 'exitfunc')
    else:
    prev_exit_func = None
    3、os._exit() Function os._exit() 函数
    os 模块的_exit()函数不应该在一般应用中使用。(平台相关,只适用特定的平台,比如基于Unix
    的平台,以及Win32 平台)。其语法为:
    os._exit(status)
    这个函数提供的功能与sys.exit()和sys.exitfunc()相反,根本不执行任何清理便立即退出
    python。与sys.exit()不同,状态参数是必需的。通过sys.exit()退出是退出解释器的首选方法。
    os.kill() Function
    os 模块的kill()函数模拟传统的unix 函数来发送信号给进程。kill()参数是进程标识数(PID)
    和你想要发送到进程的信号。发送的典型信号为SIGINT, SIGQUIT,或更彻底地,SIGKILL,来使进程
    终结。

    七、各种操作系统接口
    os 模块属性 描述
    uname() 获得系统信息(主机名,操作系统版本,补丁级别, 系统构架等等)
    getuid()/setuid(uid) 获取/设置现在进程的真正的用户ID
    getpid()/getppid() 获取真正的现在/父进程ID(PID) ○W
    getgid()/setgid(gid) 获取/设置现在进程的群组ID
    getsid()/setsid() 获取会话ID(SID)或创建和返回新的SID。
    umask(mask) 设置现在的数字unmask,同时返回先前的那个(mask 用于文件许可)○W
    getenv(ev)/
    putenv(ev, value),
    environ 获取和设置 环境变量ev 的值;os.envion 属性是描述当前所有环境变量
    的字典○W
    geteuid()/setegid() 获取/设置当前进程的有效用户ID(GID)
    getegid()/setegid() 获取/设置当前进程的有效组ID(GID)
    getpgid(pid)/
    setpgid(pid, pgrp) 获取和设置进程GID 进程PID;对于get,如果pid 为0,便返回现在进
    程的进程GID
    getlogin() 返回运行现在进程的用户登录
    times() 返回各种进程时期的元组 ○W
    strerror(code) 返回和错误代码对应的错误信息
    getloadavg()a 返回代表在过去1,5,15 分钟内的系统平均负载值的元组。

    八、执行环境相关模块。
    模块 描述
    atexita 注册当python 解释器退出时候的执行句柄
    popen2 提供额外的在os.popen 之上的功能:(提供通过标准文件和其他的进程交 互
    的能力;对于python2.4 和更新的版本,使用subpross)
    commands 提供额外的在os.system 之上的功能:把所有的程序输出保存在返回的
    字符串中(与输出到屏幕的相反);对于python2.4 和更新的版本,使
    用subpross○U
    getopt 在这样的应用程序中的处理选项和命令行参数
    site 处理site-specific 模块或包
    platformb 底层平台和架构的属性
    subprocessc 管理(计划替代旧的函数和模块,比如os.system(), os.spawn*(),
    os.popen*(), popen2.*, command.*)

  • 相关阅读:
    函数
    字符串格式化
    集合
    习题02
    int/str/list/tuple/dict必会
    元组/字典
    列表方法
    练习题(format、expandtabs、片层)
    字符串方法
    JMM
  • 原文地址:https://www.cnblogs.com/diege/p/2708911.html
Copyright © 2020-2023  润新知