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

[经验分享] Dave Python 练习十六 -- 执行环境

[复制链接]

尚未签到

发表于 2017-5-1 14:14:16 | 显示全部楼层 |阅读模式
  

  

  #encoding=utf-8###***************  执行环境  *********************##************  Part 1: 可调用对象  *****************#许多的python 对象都是我们所说的可调用的,即是任何能通过函数操作符“()”来调用的对象。#要调用可调用对象,函数操作符得紧跟在可调用对象之后。比方说,用“foo()”来调用函数"foo"。#可调用对象可以通过函数式编程接口来进行调用,如apply(),filter(),map()。#Python 有4 种可调用对象:函数,方法,类,以及一些类的实例。记住这些对象的任何引用或者别名都是可调用的。#### 1.1  函数#python 有3 种不同类型函数对象.## 1.1.1 内建函数(BIFs)#BIF 是用c/c++写的,编译过后放入python 解释器,然后把它们作为第一(内建)名字空间的#一部分加载进系统。这些函数在_bulitin_模块里,并作为__builtins__模块导入到解释器中。#内建函数属性#BIF 属性          描述#bif.__doc__       文档字符串(或None)#bif.__name__      字符串类型的文档名字#bif.__self__      设置为None(保留给built-in 方法)#bif.__module__    存放bif 定义的模块名字(或None)#可以用dir()列出函数的所有属性:#print(dir(type))#['__abstractmethods__', '__base__', '__bases__', '__basicsize__', '__call__', '__class__', #'__delattr__', '__dict__', '__dictoffset__', '__doc__', '__eq__', '__flags__', '__format__', #'__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__instancecheck__', '__itemsize__', #'__le__', '__lt__', '__module__', '__mro__', '__name__', '__ne__', '__new__', '__prepare__', #'__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasscheck__', #'__subclasses__', '__subclasshook__', '__weakrefoffset__', 'mro']#从内部机制来看,因为BIFs 和内建方法(BIMs)属于相同的类型,所以对BIF 或者BIM 调用type()的结果是:#>>> type(dir)#<type 'builtin_function_or_method'>#注意这不能应用于工厂函数,因为type()正好会返回产生对象的类型:#>>> type(int)#<type 'type'>#>>> type(type)#<type 'type'>## 1.1.2 用户定义的函数(UDF)#UDF(User-Defined Function,用户定义的函数)通常是用python 写的,定义在模块的最高级,#因此会作为全局名字空间的一部分(一旦创建好内建名字空间)装载到系统中。函数也可在其他的函#数体内定义,现在可以对多重嵌套作用域中的属性进行访问。可以用func_closure 属性来钩住在其他地方定义的属性。#用户自定义函数属性#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 表达式没有给命名绑定的代码提供基础结构,所以要通过函数式编程接口来调用,#或把它们的引用赋值给一个变量,然后就可以直接调用或者再通过函数来调用。变量仅是个别名,#并不是函数对象的名字。#通过lambda 来创建函数的对象除了没有命名之外,享有和用户自定义函数相同的属性;__name__#或者func_name 属性给定为字符串"<lambda>"。使用type()工厂函数,我们来演示下lambda 表达式#返回和用户自定义函数相同的函数对象。##>>> lambdaFunc = lambda x: x * 2#>>> lambdaFunc(100)#200#>>> type(lambdaFunc)#<type 'function'>#### 1.2  方法#用户自定义方法是被定义为类的一部分的函数。许多python 数据#类型,比如列表和字典,也有方法,这些被称为内建方法。为了进一步说明“所有权“的类型,方#法通过对象的名字和句点属性标识进行命名。#内建方法(BIM)属性#BIM 属性             描述#bim.__doc__         文档字串#bim.__name__        字符串类型的函数名字#bim.__self__        绑定的对象## 1.2.1 内建方法(BIMs)#BIM 和BIF 两者也都享有相同属性。不同之处在于BIM 的__self__属性指向一个Python对象,而BIF 指向None。#只有内建类型(BIT)有BIM.对于内建方法,type()工厂函数给出了和BIF 相同的输出--注意,我们是如何提供一个内建对象来访问BIM:#>>> type([].append)#<type 'builtin_function_or_method'>#对于类和实例,都能以该对象为参数,通过内建函数dir()来获得他们的数据和方法属性。这也可以用在BIM 上:#>>> dir([].append)#['__call__', '__class__', '__cmp__', '__delattr__', '__doc__',#'__getattribute__', '__hash__', '__init__', '__module__',#'__name__', '__new__', '__reduce__', '__reduce_ex__',#'__repr__', '__self__', '__setattr__', '__str__']## 1.2.2 用户定义的方法(UDM)#UDM(User-defined method,用户定义的方法)包含在类定义之中,只是拥有标准函数的包装,#仅有定义它们的类可以使用。如果没有在子类定义中被覆盖掉,也可以通过子类实例来调用它们。#UDM 与类对象是关联的(非绑定方法),但是只能通过类的实例来调用(绑#定方法)。无论UDMs 是否绑定,所有的UMD 都是相同的类型——“实例方法“,#>>> class C(object): # define class # 定义类#... def foo(self): pass # define UDM # 定义UDM#...#>>> c = C() # instantiation # 实例化#>>> type(C) # type of class # 类的类别#<type 'type'>#>>> type(c) # type of instance # 实例的类别#<class '__main__.C'>#>>> type(C.foo) # type of unbound method # 非绑定方法的类别#<type 'instancemethod'>#>>> type(c.foo) # type of bound method # 绑定方法的类别#<type 'instancemethod'>#用户自定义属性#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#### 1.3 类#可以利用类的可调用性来创建实例。“调用”类的结果便是创建了实例,即大家所知道的实#例化。类有默认构造函数,该函数什么都不做,基本上只有一个pass 语句。程序员可以通过实现#__int__()方法,来自定义实例化过程。实例化调用的任何参数都会传入到构造函数里。#### 1.4 类的实例#python 给类提供了名为__call__的特别方法,该方法允许程序员创建可调用的对象(实例)。默#认情况下,__call__()方法是没有实现的,这意味着大多数实例都是不可调用的。然而,如果在类#定义中覆盖了这个方法,那么这个类的实例就成为可调用的了。调用这样的实例对象等同于调用#__call__()方法.任何在实例调用中给出的参数都会被传入到__call()__中.#那么foo()就和foo.__call__(foo)的效果相同, 这里foo 也作为参数出现,因为是对自己的引用,实例将自#动成为每次方法调用的第一个参数。如果 ___call___()有参数,比如,(self, arg),那么foo(arg)就和调用foo.__call__(foo, arg)一样。#class C(object):#    def __call__(self, *args):#        print("I'm callable! Called with args:\n", args)##************  Part 2: 代码对象  *****************#可调用的对象是python 执行环境里最重要的部分,然而他们只是冰山一角。python 语句,赋值,#表达式,甚至还有模块构成了更宏大的场面。这些可执行对象无法像可调用物那样被调用。更确切#地说,这些对象只是构成可执行代码块的拼图的很小一部分,而这些代码块被称为代码对象。#每个可调用物的核心都是代码对象,由语句,赋值,表达式,以及其他可调用物组成。察看一#个模块意味着观察一个较大的、包含了模块中所有代码的对象。然后代码可以分成语句,赋值,表#达式,以及可调用物。可调用物又可以递归分解到下一层,那儿有自己的代码对象。#一般说来,代码对象可以作为函数或者方法调用的一部分来执行,也可用exec 语句或内建函数#eval()来执行。从整体上看,一个python 模块的代码对象是构成该模块的全部代码。#如果要执行python 代码,那么该代码必须先要转换成字节编译的代码(又称字节码)。这才是#真正的代码对象。然而,它们不包含任何关于它们执行环境的信息,这便是可调用物存在的原因,#它被用来包装一个代码对象并提供额外的信息。##************  Part 3: 可执行的对象声明和内建函数  *****************#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=”))### 3.1 callable()#callable()是一个布尔函数,确定一个对象是否可以通过函数操作符(())来调用。如果函数可调用便返回True,否则便是False.#print(callable(dir))#print(callable(1))#-->#True#False### 3.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')#print(eval(eval_code))#-->#300#单一可执行语句#single_code = compile('print("Hello world!")', '', 'single')#print(single_code)#exec(single_code)#-->#<code object <module> at 0x0000000002275718, file "", line 1>#Hello world!#可执行语句组#exec_code = compile("""#req = input('Count how many numbers? ')#for eachNum in range(int(req)):#    print(eachNum)#""", '', 'exec')#exec(exec_code)#-->#Count how many numbers? 4#0#1#2#3## 3.3 eval()#eval()对表达式求值,后者可以为字符串或内建函数complie()创建的预编译代码对象。这是#eval()第一个也是最重要的参数。第二个和第三个参数,都为可选的,分别代表了全局和局部名字空间中的对象。#如果给出这两个参数,globals 必须是个字典,locals可以是任意的映射对象,比如,一个实现了__getitem__()方法的对象。#如果都没给出这两个参数,分别默认为globals()和locals()返回的对象,如果只传入了一个全局字典,那么该字典也作为locals 传入。#print(eval('932'))#932#print(int('932'))#932##    在这种情况下,eval()和int()都返回相同的结果:整数932。然而,它们采用的方式却不尽相#同。内建函数eval()接收引号内的字符串并把它作为python 表达式进行求值。内建函数int()接收#代表整数的字符串并把它转换为整数。这只有在该字符串只由字符串932 组成的时候才会成功,而#该字符串作为表达式返回值932,932 也是字符串”932”所代表的整数。当我们用纯字符串表达式#的时候,两者便不再相同了:#print(eval('100 + 200'))#300#print(int('100 + 200'))#ValueError: invalid literal for int(): 100 + 200## 3.4 exec#和eval()相似,exec 语句执行代码对象或字符串形式的python 代码。类似地,用compile()#预编译重复代码有助于改善性能,因为在调用时不必经过字节编译处理。exec 语句只接受一个参数,#下面便是它的通用语法:#exec obj#被执行的对象(obj)可以只是原始的字符串,比如单一语句或是语句组,它们也可以预编译成#一个代码对象(分别用'single'和'exec"参数)#exec_code = compile("""#req = input('Count how many numbers? ')#for eachNum in range(int(req)):#    print(eachNum)#""", '', 'exec')#exec(exec_code)## 3.5 input() #内建函数input()是eval()和raw_input()的组合,等价于eval(raw_input())。类似于#raw_input(),input()有一个可选的参数,该参数代表了给用户的字符串提示。如果不给定参数的#话,该字符串默认为空串。#从功能上看,input 不同于raw_input(),因为raw_input()总是以字符串的形式,逐字地返回用#户的输入。input()履行相同的的任务;而且,它还把输入作为python 表达式进行求值。这意味着#input()返回的数据是对输入表达式求值的结果:一个python 对象。##************  Part 4: 执行其他(非Python)程序  *****************#在python 程序里我们也可以执行非python 程序。这些程序包括了二进制可执行文件,其他的#shell 脚本等等。所有的要求只是一个有效的执行环境,比如,允许文件访问和执行,脚本文件必须#能访问它们的解释器(perl, bash,等等),二进制必须是可访问的(和本地机器的构架兼容)#执行外部程序的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## 4.1 os.system()#system(),一个非常简单的函数,接收字符串形式的系统命令并执行它。当执行命令的时候,python 的运行是挂起的。#当我们的执行完成之后,将会以system()的返回值形式给出退出状态,python 的执行也会继续。#system()保留了现有的标准文件,包括标准的输出,意味着执行任何的命令和程序显示输出都#会传到标准输出上。这里要当心,因为特定应用程序比如公共网关接口(CGI),如果将除了有效的超#文本标示语言(HTML)字符串之外的输出,经过标准输出发送回客户端,会引起web 浏览器错误。#system()通常和不会产生输出的命令一起使用,其中的一些命令包括了压缩或转换文件的程序,挂#载磁盘到系统的程序,或其他执行特定任务的命令---通过退出状态显示成功或失败而不是通过输入#和/或输出通信。通常的约定是利用退出状态,0 表示成功,非零表示其他类型的错误。#import os#result = os.system('uname -a')#print(result)## 4.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)##************  Part 5: 结束执行  *****************#当程序运行完成,所有模块最高级的语句执行完毕后退出,我们便称这是干净的执行。可能有#很多情况,需要从python 提前退出,比如某种致命错误,或是不满足继续执行的条件的时候。#在python 中,有各种应对错误的方法。其中之一便是通过异常和异常处理。另外一个方法便是#建造一个“清扫器”方法,这样便可以把代码的主要部分放在if 语句里,在没有错误的情况下执行,#因而可以让错误的情况“正常地“终结。然而,有时也需要在退出调用程序的时候,返回错误代码#以表明发生何种事件。## 5.1 sys.exit() and SystemExit#立即退出程序并返回调用程序的主要方式是sys 模块中的exit()函数。sys.exit()的语法为:#    sys.exit(status=0)#当调用sys.exit()时,就会引发systemExit()异常。除非对异常进行监控(在一个try 语句和#合适的except 子句中),异常通常是不会被捕捉到或处理的,解释器会用给定的状态参数退出,如#果没有给出的话,该参数默认为0。System Exit 是唯一不看作错误的异常。它仅仅表示要退出python#的愿望。#sys.exit()经常用在命令调用的中途发现错误之后,比如,如果参数不正确,无效,或者参数数目不正确。## 5.2 sys.exitfunc()#sys.exitfunc()默认是不可用的,但你可以改写它以提供额外的功能。当调用了sys.exit()并#在解释器退出之前,就会用到这个函数了。这个函数不带任何参数的,所以你创建的函数也应该是#无参的。#如果sys.exitfunc 已经被先前定义的exit 函数覆盖了,最好的方法是把这段代码作为你exit()#函数的一部分来执行。一般说来,exit 函数用于执行某些类型的关闭活动,比如关闭文件和网络连#接,最好用于完成维护任务,比如释放先前保留的系统资源。## 5.3 os._exit()和 os._exit() 函数#os 模块的_exit()函数不应该在一般应用中使用。(平台相关,只适用特定的平台,比如基于Unix#的平台,以及Win32 平台)。其语法为:#os._exit(status)#这个函数提供的功能与sys.exit()和sys.exitfunc()相反,根本不执行任何清理便立即退出#python。与sys.exit()不同,状态参数是必需的。通过sys.exit()退出是退出解释器的首选方法。## 5.4 os.kill()#os 模块的kill()函数模拟传统的unix 函数来发送信号给进程。kill()参数是进程标识数(PID)#和你想要发送到进程的信号。发送的典型信号为SIGINT, SIGQUIT,或更彻底地,SIGKILL,来使进程终结。


  

  

  

  -------------------------------------------------------------------------------------------------------
Blog: http://blog.csdn.net/tianlesoftware
Weibo: http://weibo.com/tianlesoftware
Email: dvd.dba@gmail.com
DBA1 群:62697716(满);  DBA2 群:62697977(满)  DBA3 群:62697850(满)
DBA 超级群:63306533(满); DBA4 群: 83829929(满) DBA5群: 142216823(满)
DBA6 群:158654907(满)  DBA7 群:69087192(满)  DBA8 群:172855474
DBA 超级群2:151508914 DBA9群:102954821   聊天 群:40132017(满)
--加群需要在备注说明Oracle表空间和数据文件的关系,否则拒绝申请

运维网声明 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-371699-1-1.html 上篇帖子: Python学习入门基础教程(learning Python)--5.7 Python文件数据记录存储与处理 下篇帖子: Dave Python 练习十二 -- 错误和异常
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

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

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

扫描微信二维码查看详情

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


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


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


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



合作伙伴: 青云cloud

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