设为首页 收藏本站
查看: 322|回复: 0

[经验分享] python核心编程学习笔记-执行环境

[复制链接]

尚未签到

发表于 2017-5-1 11:44:53 | 显示全部楼层 |阅读模式
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 文件对象:
[iyunv@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
>>> 
 
2)execfile():导入模块不是执行其他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)         等待指定的子进程完成[通常和fock和exec*()一起使用]
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():执行文件, 打开文件, 从新创建的运行程序读取(stdout和stder) ,
或者向该程序写(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。
 
[iyunv@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
[iyunv@localhost python]# ./args.py
At least 2 arguments (incl. cmd name).
usage: args.py arg1 arg2 [arg3... ]
[iyunv@localhost python]# ./args.py xxx
At least 2 arguments (incl. cmd name).
usage: args.py arg1 arg2 [arg3... ]
[iyunv@localhost python]# ./args.py 123 abc
number of args entered: 3
args (incl. cmd name) were: ['./args.py', '123', 'abc']
[iyunv@localhost python]#
[iyunv@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() 获取/设置当前进程的有效用户 ID(GID)
getegid()/setegid() 获取/设置当前进程的有效组 ID(GID)
getpgid(pid)/ setpgid(pid, pgrp)     获取和设置进程 GID 进程 PID;对于 get,如果 pid 为 0,便返回现在进程的进程 GID
getlogin()          返回运行现在进程的用户登录
strerror(code)       返回和错误代码对应的错误信息
getloadavg()        返回代表在过去 1,5,15 分钟内的系统平均负载值的元组。
 
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.*)

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-371585-1-1.html 上篇帖子: Python多线程学习-壹-threading 下篇帖子: python遍历文件夹和文件
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表