python核心编程学习笔记-执行环境

14.1、可调用对象

函数:

1)  内建函数(BIFs

BIF是用 c/c++写的,编译过后放入 python 解释器,然后把它们作为第一(内建)名字空间的一部分加载进系统。这些函数在_bulitin_模块里,并作为__builtins__模块导入到解释器中。

内建函数属性:

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

bif.__name__:字符串类型的文档名字

bif.__self__:设置为 None(保留给 built-in 方法)

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

 

BIF 有基础类型属性,dir()列出函数的所有属性:

>>> dir(type)

['__base__', '__bases__', '__basicsize__', '__call__', '__class__', '__cmp__', '__delattr__', '__dict__', '__dictoffset__', '__doc__', '__flags__', '__getattribute__', '__hash__', '__init__', '__itemsize__', '__module__', '__mro__', '__name__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__', '__subclasses__', '__weakrefoffset__', 'mro']

 

BIFs和内建方法BIMs属于相同的类型:

>>> type(dir)

 

 

不能应用于工厂函数,type()返回产生对象类型:

>>> type(int)

 

>>> type(type)

 

 

2)用户定义的函数(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 包含了自由变量的引用的单元对象元组(

 

自定义的函数是“函数”类型:

>>> def foo():pass

...

>>> type(foo)

 

 

3)  lambda表达式函数

lambda创建的函数对象没有命名,需要通过函数式编程接口来调用,或将引用赋值给变量后再调用,变量仅是别名。lambda__name__属性。

 

>>> lambdaFunc=lambda x:x*2

>>> lambdaFunc(100)

200

>>> type(lambdaFunc)

 

>>> type(lambda:1)          #lambda表达式调用type()

 

 

>>> foo.__name__

'foo'

>>> lambdaFunc.__name__

''

 

方法:

用户自定义方法是被定义为类的一部分的函数,列表和字典,也有方法,这些被称为内建方法,方法通过对象的名字和句点属性标识进行命名。

1)  内建方法(BIFs

BIM属性:

bim.__doc__     文档字串

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

bim.__self__ 绑定的对象

 

内建对象访问BIM:

>>> type([].append)

 

 

通过内建函数dir()获取数据和方法属性:

>>> dir([].append)

['__call__', '__class__', '__cmp__', '__delattr__', '__doc__', '__getattribute__', '__hash__', '__init__', '__module__', '__name__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__self__', '__setattr__', '__str__']

 

2)用户定义方法(UDM

UDM包含在类定义之中, 只是拥有标准函数的包装,仅有定义它们的类可以使用。如果没有在子类定义中被覆盖掉,也可以通过子类实例来调用它们。UDM 与类对象是关联的(非绑定方法) ,但是只能通过类的实例来调用(绑定方法) 。无论 UDMs 是否绑定,所有的 UMD 都是相同的类型——“实例方法“

>>> class C(object):          # 定义类

...     def foo(self):pass        # 定义UDM

...

>>> c=C()          # 实例化

>>> type(C)      # 类的类别

 

>>> type(c)       # 实例的类别

 

>>> type(C.foo)        # 非绑定方法的类别

 

>>> type(c.foo)         # 绑定方法的类别

 

 

访问对象本身显示引用绑定或非绑定方法:

>>> C.foo          # 非绑定方法对象

 

>>> c.foo           # 绑定方法对象

<__main__.C object at 0xb7e71f8c>>

 

用户自定义属性:

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

 

类:

 

14.2、代码对象

每个可调用物的核心都是代码对象,由语句,赋值,表达式,以及其他可调用物组成。

一般说来,代码对象可以作为函数或者方法调用的一部分来执行,也可用 exec 语句或内建函数eval_r()来执行。

 

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

callable(obj)    如果 obj 可调用,返回 True,否则返回 FALSE

compile(string,file, type)  从 type 类型中创建代码对象;file 是代码存放的地方(通常设

"")

eval_r(obj, glo- bals=globals(), locals=locals()) 对 obj 进行求值,obj 是已编译为代码对象的表达式,或是一个字符串表达式;可以给出全局或者/和局部的名字空间

exec obj 执行 obj、单一的 python 语句或者语句的集合,也就是说格式是代码对象或者字符串;obj 也可以是一个文件对象(已经打开的有效 python 脚本中)

input(prompt='')    等同于 eval_r(raw_input(prompt=))

 

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

调用便返回 True,否则便是 False

>>> callable(dir)       # 内建函数

True

>>> callable(1)          #整数

False

>>> def foo():pass

...

>>> callable(foo)      # 用户自定义函数

True

>>> callable('bar')    # string  #字符串

False

>>> class C(object):pass

...

>>> callable(C)          #

True

 

compile():允许程序员在运行时刻迅速生成代码对象,然后就可以用 exec 语句或者内建函

数 eval_r()来执行这些对象或者对它们进行求值。exec 和 eval_r()都可以执行字符串格式的 Python 代码。当执行字符串形式的代码时,每次都必须对这些代码进行字节编译处理。

compile()函数提供了一次性字节代码预编译,以后每次调用的时候,都不用编译了。

compile 的三个参数都是必需的,第一参数代表了要编译的 python 代码。第二个字符串通常被置为空串。该参数代表了存放代码对象的文件的名字(字符串类型)。最后参数是字符串,表明代码对象的类型,有以下三个可能值:

'eval'  可求值的表达式[和 eval_r()一起使用]

'single'     单一可执行语句[和 exec 一起使用]

'exec'    可执行语句组[和 exec 一起使用]

 

求值表达式:

>>> eval_code = compile('100 + 200', '', 'eval')

>>> eval_r(eval_code)

300

 

单一可执行语句:

>>> single_code=compile('print "Hello world!"','','single')

>>> single_code

>>> 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

 

eval_r():对表达式求值

>>> eval_r('932')         #eval_r()接收引号内的字符串并把它作为 python 表达式进行求值

932

>>> int('932')           #int()接收代表整数的字符串并把它转换为整数。

932

>>>

>>> eval_r('100+200')

300

>>> int('100+200')           #字符串表达式报错

Traceback (most recent call last):

  File "", line 1, in ?

ValueError: invalid literal for int(): 100+200

 

exec():和 eval_r()相似,exec 语句执行代码对象或字符串形式的 python 代码。

被执行的obj对象参数可以只是原始的字符串,比如单一语句或是语句组,它们也可以预编译成一个代码对象 (分别用'single''exec"参数)

>>> exec """

... x=0

... print 'x is currently:',x

... while x<5:

...     x+=1

...     print 'incrementing x to:',x

... """

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 还可接受有效的 python 文件对象:

[root@localhost python]# cat xcount.py

#!/usr/binpython

x=0

print 'x is currently:',x

while x<5:

    x+=1

print 'incrementing x to:',x

 

>>> f=open('/root/python/xcount.py')

>>> exec  f

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执行完毕后继续对exec调用将会失败,因为相同文件对象被exec调用的时候,已经到了文件末尾(EOF),所有在次调用没有代码可执行了,所有exec会什么都不做。

使用文件对象的tell()方法查看处于文件的位置,os.path.getsize()查看脚本有多大。

>>> f.tell()

100L

>>> f.close()

>>> from os.path import getsize

>>> getsize('/root/python/xcount.py')

100L

 

不关闭和重打开文件再次运行,使用seek()到文件的最开头再次调用exec

>>> f=open('/root/python/xcount.py')

>>> exec f

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         #再次调用无效

>>> f.seek(0)

>>> exec f

x is currently: 0

incrementing x to: 1

incrementing x to: 2

incrementing x to: 3

incrementing x to: 4

incrementing x to: 5

 

input()

内建函数 input()是 eval_r()和 raw_input()的组合,等价于 eval_r(raw_input())。类似于raw_input()input()有一个可选的参数,该参数代表了给用户的字符串提示。如果不给定参数的话,该字符串默认为空串。

 

从功能上看,input 不同于 raw_input(),因为 raw_input()总是以字符串的形式,逐字地返回用户的输入。input()履行相同的的任务;而且,它还把输入作为 python 表达式进行求值。这意味着input()返回的数据是对输入表达式求值的结果:一个 python 对象。

>>> aString = raw_input('Enter a list: ')

Enter a list: [ 123, 'xyz', 45.67 ]

>>> aString

"[ 123, 'xyz', 45.67 ]"

>>> type(aString)

 

>>>

>>> aList = input('Enter a list: ')

Enter a list: [ 123, 'xyz', 45.67 ]

>>> aList

[123, 'xyz', 45.67]

>>> type(aList)

 

 

14.4、执行其他python程序

1)导入:第一次导入模块会执行模块最高级别的(没有缩进的)代码。如何处理那些不想每次导入都执行的代码呢?缩进它,并放入 if __name__ == '__main__' 的内部。

# import1.py

print 'loaded import1'

import import2       #导入import2.py模块

 

# import2.py

print 'loaded import2'

 

>>> import import1          #执行导入import1

loaded import1

loaded import2

 

上面导入后便执行,改进代码如下:

# import1.py

import import2

if __name__ == '__main__':

print 'loaded import1'

 

# import2.py

if __name__ == '__main__'

print 'loaded import2'

 

>>>import import1           #不再执行print

>>> 

 

2execfile():导入模块不是执行其他python脚本的最好方法,execfile语法:

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

globals 和 locals 都是可选的,如果不提供参数值的话,默认为执行环境的名字空间。如果只给定 globals,那么 locals 默认和 globals 相同。如果提供 locals 值的话,它可以是任何映射对象。

f = open(filename, 'r')

exec f

f.close()

 

execfile(filename)

 

3)将模块作为脚本执行

$ python /usr/local/lib/python2x/CGIHTTPServer.py

 

python -c 命令行开关:  

$ python -c "import CGIHTTPServer; CGIHTTPServer.test()"

 

$ python -m CGIHTTPServer

 

14.5、执行其他非Python程序

执行外部程序的 os 模块函数:

system(cmd) 执行程序 cmd(字符串),等待程序结束,返回退出代码

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*(mode, file, args[, env])     spawn*()家族在一个新的进程中执行路径,args 作为

参数,也许还有环境变量的字典 env;模式(mode)是个显示不同操作模式的魔术。

wait()       等待子进程完成[通常和 fock 和 exec*()一起使用]

waitpid(pid,options)         等待指定的子进程完成[通常和fockexec*()一起使用]

popen(cmd, mode='r',buffering=-1)    执行字符串 cmd,返回一个类文件对象作为运行程序通信句柄,默认为读取模式和默认系统缓冲

 

python2.4 或者更新版本有 subprocess 模块,可以作为上面所有函数很好的替代品。

 

os.system():接收字符串形式的系统命令并执行它。当执行命令的时候,python 的运行是挂起的。当我们的执行完成之后,将会以 system()的返回值形式给出退出状态,python 的执行也会继续。

>>> import os

>>> result=os.system('dir')

python

>>>

>>>

>>> import os

>>> result=os.system('df -h')

Filesystem            Size  Used Avail Use% Mounted on

/dev/mapper/VolGroup00-LogVol00

                       16G  4.6G   11G  31% /

/dev/sda1              99M   13M   82M  13% /boot

tmpfs                 246M     0  246M   0% /dev/shm

>>> result=os.system('free')

             total       used       free     shared    buffers     cached

Mem:        502680      68784     433896          0      13296      36496

-/+ buffers/cache:      18992     483688

Swap:      3670008          0    3670008

>>> result=os.system('uptime')

 23:54:04 up  5:45,  3 users,  load average: 0.00, 0.00, 0.00

 

os.open():是文件对象和 system()函数的结合。它工作方式和 system()相同,但它可以建立

一个指向那个程序的单向连接,然后如访问文件一样访问这个程序。popen()返回一个类文件对象。

 

>>> import os

>>> f=os.popen('uname -a')

>>> data=f.readline()

>>> f.close()     #当使用完毕以后,应当 close()连接。

>>> print data,

Linux localhost.localdomain 2.6.18-238.el5 #1 SMP Thu Jan 13 16:24:47 EST 2011 i686 i686 i386 GNU/Linux

 

os.fork(), os.exec*(),os.wait*(), os.spawn*():略

 

subprocess 模块:

替换os.system()

>>> from subprocess import call

>>> import os

>>> res=call(('cat','/etc/motd'))

welcome to python world!

>>> res

0

 

取代os.popen()

>>> from subprocess import Popen, PIPE

>>> f = Popen(('uname', '-a'), stdout=PIPE).stdout

>>> data = f.readline()

>>> f.close()

>>> print data,

Linux localhost.localdomain 2.6.18-238.el5 #1 SMP Thu Jan 13 16:24:47 EST 2011 i686 i686 i386 GNU/Linux

>>> f = Popen('who', stdout=PIPE).stdout

>>> data = [ eachLine.strip() for eachLine in f ]

>>> f.close()

>>> for eachLine in data:

...     print eachLine

...

root     pts/0        2012-10-20 18:10 (192.168.128.1)

root     pts/1        2012-10-20 20:30 (192.168.128.1)

root     pts/2        2012-10-20 23:07 (192.168.128.1)

 

相关函数:

os/popen2.popen2():执行文件,打开文件,从新创建的运行程序读取(stdout),或者向

该程序写(stdin) 

os/popen2.popen3():执行文件, 打开文件, 从新创建的运行程序读取(stdoutstder) ,

或者向该程序写(stdin) 

os/popen2.popen4():执行文件,打开文件,从新创建的运行程序读取(结合 stdout

stdout),或者向该程序写(stdin) 

commands.getoutput():在子进程中执行文件,以字符串返回所有的输出

subprocess.call():创建 subprocess 的便捷函数。 Popen 等待命令完成,然后返回状

态代码;与 os.system()类似,但是是较灵活的替代方案

 

14.6、受限执行()

14.7、结束执行

当程序运行完成,所有模块最高级的语句执行完毕后退出,我们便称这是干净的执行。可能有很多情况,需要从 python 提前退出,比如某种致命错误,或是不满足继续执行的条件的时候。

处理错误方法之一是通过异常和异常处理。另外一个方法便是建造一个 “清扫器” 方法, 这样便可以把代码的主要部分放在 if语句里, 在没有错误的情况下执行,因而可以让错误的情况“正常地“终结。然而,有时也需要在退出调用程序的时候,返回错误代码以表明发生何种事件。

 

sys.exit() and SystemExit

立即退出程序并返回调用程序的主要方式是 sys 模块中的 exit()函数。sys.exit()的语法为:

sys.exit(status=0)

当调用 sys.exit()时,就会引发 systemExit()异常。除非在一个 try-except 子句中,异常通常是不会被捕捉到或处理的,解释器会用给定的状态参数退出,如果没有给出的话, 该参数默认为 0。 System Exit 是唯一不看作错误的异常。仅表示要退出python

 

[root@localhost python]# more args.py

#!/usr/bin/env python

import sys

def usage():

        print 'At least 2 arguments (incl. cmd name).'

        print 'usage: args.py arg1 arg2 [arg3... ]'

        sys.exit(1)

argc = len(sys.argv)

if argc < 3:

        usage()

print "number of args entered:", argc

print "args (incl. cmd name) were:", sys.argv

[root@localhost python]# ./args.py

At least 2 arguments (incl. cmd name).

usage: args.py arg1 arg2 [arg3... ]

[root@localhost python]# ./args.py xxx

At least 2 arguments (incl. cmd name).

usage: args.py arg1 arg2 [arg3... ]

[root@localhost python]# ./args.py 123 abc

number of args entered: 3

args (incl. cmd name) were: ['./args.py', '123', 'abc']

[root@localhost python]#

[root@localhost python]# ./args.py -x -2 foo

number of args entered: 4

args (incl. cmd name) were: ['./args.py', '-x', '-2', 'foo']

 

sys.exitfunc():默认是不可用的,但你可以改写它以提供额外的功能。当调用了 sys.exit()

在解释器退出之前,就会用到这个函数了,这个函数不带任何参数。

 

os._exit() 函数,语法:os._exit(status)

功能与 sys.exit()和 sys.exitfunc()相反,根本不执行任何清理便立即退出python。与 sys.exit()不同,状态参数是必需的。通过 sys.exit()退出是退出解释器的首选方法。

 

os.kill()os 模块的 kill()函数模拟传统的 unix 函数来发送信号给进程。kill()参数是进程标识数(PID)和你想要发送到进程的信号。发送的典型信号为 SIGINT, SIGQUIT,或更彻底地,SIGKILL,来使进程终结。

 

14.8、操作系统接口

各种os模块属性(省略windows)

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

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

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

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

geteuid()/setegid() 获取/设置当前进程的有效用户 IDGID

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

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

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

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

getloadavg()        返回代表在过去 1515 分钟内的系统平均负载值的元组。

 

14.9、执行环境相关模块

atexit       注册当 python 解释器退出时候的执行句柄

popen2             提供额外的在os.popen之上的功能: (提供通过标准文件和其他的进程交的能力;对于 python2.4 和更新的版本,使用 subpross

commands   提供额外的在 os.system 之上的功能:把所有的程序输出保存在返回的字符串中(与输出到屏幕的相反) ;对于python2.4 和更新的版本,使用 subpross

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

site         处理 site-specific 模块或包

platform     底层平台和架构的属性

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值