Python执行环境

版权声明:此文章转载自infocool

原文链接:http://www.infocool.net/kb/Python/201607/166348.html

如需转载请联系听云College团队成员小尹 邮箱:yinhy#tingyun.com

1、可调用对象 

许多Python对象都是可调用的,即任何能通过函数操作符“()”来调用的对象。Python有4种可调用对象:函数、方法、类以及一些类实例,这些对象的任何引用或者别名都是可调用的。 

(1)函数(3种函数) 

①内建函数(BIF,built-in function) 

由C/C++写的,编译过后放入Python解释器,然后把它们作为第一(内建)名称空间的一部分加载进系统。这些函数在_builtin_模块里,并作为_builtins_模块导入到解释器中。 

内建函数的属性包括:

bif.__doc__ 文档字符串(或None)

bif.__name__ 字符串类型的函数名字

bif.__self__ 设置为None(保留给内建方法)

bif.__module__ 存放bif定义的模块名字(或None)

②用户定义的函数(UDF,user-defined function) 

用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 包含了自由变量的引用的单元对象元组

③lambda表达式 

用lambda关键字创建,不使用def语句创建。 

用lambda关键字创建的函数对象没有命名,需要将其引用赋值给一个变量才可以被调用。 

用lambda关键字创建的函数对象和用户自定义函数具有相同的属性。 

(2)方法 

①内建方法(BIM) 

只有内建类型(BIT)才有内建方法。BIM和BIF调用type()具有相同的结果builtin_function_or_method。BIM和BIF两者都具有相同属性。不同之处在于BIM的__self__属性指向一个Python对象,而BIF指向None。 

对于类和实例都可以以该对象为参数调用内建函数dir()来获得它们的数据和方法属性。 

②用户定义的方法(UDM) 

包含在类定义之中,仅有定义它们的类可以使用。 

UDM与类对象是关联的(非绑定方法),但是只能通过类的实例来调用(绑定方法)。 

无论UDM是否绑定,所有的UDM都是相同的类型–“实例方法”。 

UDM包含的常用属性有:

udm.__doc__ 文档字符串(与udm.im_func.__doc__相同)

udm.__name__ 字符串类型的方法名字(与udm.im_func.__name__相同)

udm.__module__ 定义udm的模块的名字(或None)

udm.im_class 方法相关联的类(对于绑定的方法;如果是非绑定,那么为要求udm的类)

udm.im_func 方法的函数对象

udm.im_self 如果绑定的话为相关联的实例,如果非绑定为None

(3)类 

“调用”类的结果便是创建了类实例。程序员可以通过实现__init__()方法来自定义实例化过程。调用类时,传入的参数都会交给__init__()方法。 

(4)类的实例 

Python给类提供了特殊方法__call__(),允许程序员创建可调用的对象(实例)。 

默认情况下,该方法没有实现,所以大多数实例是不可调用的。在类定义中覆盖该方法,类的实例就成为可调用对象了。

class C(object):
    def __call__(self,*args):
        ....
>>>c=C()
>>>c() #调用实例

调用这样的实例对象等同于调用__call__()方法。任何实例调用中给出的参数都会传入到__call__()方法中。 

c()与c.__call__(c)的效果相同,c(arg)与c.__call__(c,arg)一样,这里c也作为参数出现,是因为实例将作为每次方法调用的第一个参数。

2、代码对象 

可调用物由代码对象构成。 

代码对象包括语句、赋值、表达式和其他可调用物组成。 

代码对象可以作为函数或者方法调用的一部分来执行,也可用exec语句或内建函数eval()来执行。代码对象转换成字节码,然后包含执行环境(可调用物),便可以执行了。

3、可执行的对象声明和内建函数 

(1)callable() 

布尔函数,确定一个对象是否可以通过函数操作符(())来调用。 

(2)compile() 

允许在运行时刻迅速生成代码对象,然后调用exec语句或内建函数eval()来执行它们。exec语句和eval()内建函数都可以执行字符串形式的代码。compile()函数提供一次性字节代码预编译。

compile(string,file,type)

string表示要编译的Python代码,必须。 

file表示存放代码对象的文件的名字(字符串类型),虽然必须,但是通常被置为空。 

type表示代码对象的类型,有三个可能值:

eval’:可求值的表达式(与eval()一起使用)

‘single’:单一可执行语句(与exec一起使用)

‘exec’:可执行语句组(与exec一起使用)

(3)eval() 

对表达式求值,可以是字符串或内建函数compile()创建的预编译代码对象。

eval(obj,globals=globals(),locals=locals())

obj 是字符串或是已编译为代码对象的表达式,globals必须是字典,locals可以是任意的映射对象。 

(4)exec语句 

exec语句执行代码对象或字符串形式的Python代码。exec语句还可以接受有效的Python文件对象。一旦执行完毕,继续对exec的调用就会失败,因为第一次执行时,exec已经从文件中读取了全部的数据且停留在文件的末尾,可以使用file对象的tell()方法来告诉我们处于文件的何处,同时使用os.path.getsiae()来告诉我们文件的大小,就可以确认是否到达了文件的末尾。可以调用file对象的seek()方法到文件的开头再次调用exec。

exec obj

(5)input() 

它是eval()和raw_input()的组合,等价于eval(raw_input())。将用户输入作为Python表达式进行求值。input()方法返回一个Python对象。

4、执行其他(Python)程序 

(1)导入 

第一次导入模块会执行模块最高级的代码。 

Python解释器通过检测__name__来确定是否要调用脚本,比如”if __name__==’__main__’”,若相等的话,脚本会执行main内代码,否则只是打算导入这个脚本。 

(2)execfile()

execfile(filename,globals=globals(),locals=locals())

语法类似于eval()函数,globals和locals都是可选的,如果不提供globals和locals,默认为执行环境的名称空间;如果只提供globals,locals默认和globals相同。 

方法1:

f=open(filename,'r')
exec f 
f.close()

<=> 

方法2:

execfile(filename)

方法1仅可以在现有的执行环境下运行,方法2可以在指定的全局和局部的名称空间执行。 

(3)将模块作为脚本执行(2.4) 

①从shell或DOS提示符直接把模块作为脚本来执行

$ myScript.py #从工作目录调用脚本
or
$ python myScript.py

②如果模块是标准库的一部分,安装在site-packages里,或者仅仅是包里面的模块,需要提供完整路径或借助于Python的导入机制来工作。

$ python -c "import CGIHTTPServer;CGIHTTPServer.test()" #让Python导入机制工作
or
$ python /usr/local/lib/python2x/CGIHTTPServer.py #完整路径名
or
$ python -m CGIHTTPServer #能在类库中执行作为脚本的模块而不是作为导入

5、执行其他(非Python)程序 

其他的非Python程序包括:二进制可执行文件,其他的shell脚本等。 

执行其他的非Python程序需要满足的条件:一个有效的执行环境,如允许文件访问和执行,脚本文件必须能访问它们的解释器,二进制必须是可访问的。 

(1)os.system() 

接受字符串形式的系统命令并执行它。 

执行命令时,Python运行被挂起,命令执行完,将以system()的返回值形式给出退出状态,Python继续执行。 

system()通常和不会产生输出的命令一起使用,如压缩或转换文件的程序,挂载磁盘到系统的程序,返回值0表示成功,非0表示其他类型的错误。 

(2)os.popen() 

popen()函数是文件对象和system()函数的结合。

>>>f=os.popen('uname -a')
>>>data=f.readline()
>>>f.close()
>>>print data

popen()的工作方式和system()相同,但可以通过指向程序的单向连接,像访问文件一样访问程序。popen()返回一个类文件对象。 

(3)os.fork(),os.exec*(),os.wait*() 

os.fork()创建一个和父进程并行的子进程(通常来说和exec*()一起使用);返回两次…一次给父进程一次给子进程 

os.exec*()函数装载文件或者命令,并用参数列表来执行它。 

(4)os.spawn*() 

(5)subprocess模块

**6、结束执行 

(1)sys.exit()和SystemExit异常** 

sys.exit()立即退出程序并返回调用程序。当调用sys.exit()时,就会引发SystemExit异常。SystemExit异常是唯一不看作错误的异常,仅仅表示要退出Python的愿望。sys.exit()经常用在命令调用的中途发现错误之后。 

(2)sys.exitfunc() 

当调用了exit()函数并在解释器退出之前,就会用到这个函数,该函数默认是不可用的,你可以改写它以提供额外的功能。 

(3)os._exit()函数 

os._exit()函数与sys.exit()和sys.exitfunc()相反,根本不执行任何清理便立即退出Python。 

os._exit(status) 状态参数status是必需的。通过sys.exit()退出是解释器的首选方法。 

(4)os.kill()函数 

kill()函数模拟传统的unix函数发送信号给进程,参数为进程标识符(PID)和信号,信号常见的有SIGINT,SIGQUIT,SIGKILL等。

7、各种操作系统接口 

除非标明适用于Windows环境,否则只适用于POSIX系统。

uname() 获得系统信息(主机名、操作系统版本、补丁级别、系统结构等)

getuid()/setuid(uid) 获取/设置现在进程的真正的用户ID

getpid()/getppid() 获取真正的现在/父进程ID(PID)(Win32)

getgid()/setgid(gid) 获取/设置现在进程的群组ID

getsid()/setsid() 获取会话ID(SID)或创建和返回新的SID

umask(mask) 设置现在的数字umask,同时返回先前的那个(mask用于文件许可)(Win32)

getenv(ev)/putenv(ev,value),environ获取和设置环境变量ev的值;

os.environ属性是描述当前所有环境变量的字典(Win32)

geteuid()/seteuid() 获取/设置当前进程的有效用户ID(UID)

getegid()/setegid() 获取/设置当前进程的有效组ID(GID)

getpgid(pid)/setpgid(pid,pgrp) 获取/设置PID进程的GID;对于get,如果pid为0,便返回现在进程的GID

getlogin() 返回运行现在进程的用户登录

times() 返回各种进程时期的元组(Win32)

strerror(code) 返回和错误代码对应的错误信息(Win32)

getloadavg()(2.3) 返回代表在过去1,5,15分钟内的系统平均负载值的元组

8、相关模块

atexit(2.0) 注册当Python解释器退出时的执行句柄

popen2 提供额外的在os.popen之上的功能;提供通过标准文件和其他的进程交互的能力

commands 提供额外的在os.sysytem之上的功能;把所有的程序输出保存在返回的字符串中(与输出到屏幕的相反)

getopt 在这样的应用程序中的处理选项和命令行参数

site 处理site-specific模块或包

platform(2.3) 底层平台和架构的属性

subprocess(2.4)管理(计划替代旧的函数和模块,比如os.system()、os.spawn*()、os.popen*()、popen2.和commands.)

1.png

想阅读更多技术文章,请访问听云技术博客,访问听云官方网站感受更多应用性能优化魔力。

关于作者

郝淼emily

重新开始,从心开始

我要评论

评论请先登录,或注册