[PYTHON] 核心編程筆記(14.Python執行環境)

在python中有多種運行外部程序的方法,比如,運行操作系統命令或另外的python腳本,或執行一個磁盤上的文件,或通過網絡來運行文件


在特定執行場景包括:

在當前腳本繼續運行

創建和管理子進程

執行外部命令或程序

執行需要輸入的命令

通過網絡來調用命令

執行命令來創建需要處理的輸出

執行其他python腳本

執行一系列動態生成的Python語句

導入Python模塊


Python中,內建和外部模塊都可以提供上述功能,程序員得根據實現的需要,從這些模塊中選擇合適的處理方法


14.1 可調用對象

即任何能夠通過函數操作符"()"來調用的對象,函數操作符得緊跟在可調用對象之後,比如,用"foo()"來調用函數"foo"


14.1.1 函數


內建函數(BIFs):

BIF是用c/c++寫的,編譯過後放入python解釋器,然後把他們作爲第一(內建)名字空間的一部分加載進系統


BIF 屬性描述

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

bif.__name__字符串類型的文檔名字

bif.__self__設置爲None(保留給built-in方法)

bif.__module__存放bif定義的模塊名字(或None)


用dir()流出函數的所有屬性:

>>> 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__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasscheck__', '__subclasses__', '__subclasshook__', '__weakrefoffset__', 'mro']


>>> type(dir)

<type 'builtin_function_or_method'>


>>> type(int)

<type 'type'>

>>> type(type)

<type 'type'>


用戶定義的函數(UDF)


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)

<type 'function'>


使用type()工廠函數,我們來演示下lambda表達式返回和用戶自定義函數相同的函數對象

將表達式賦值給一個別名

>>> type(foo)

<type 'function'>

>>> lambdaFunc = lambda x : x * 2

>>> lambdaFunc(100)

200

>>> type(lambdaFunc)

<type 'function'>


在一個lambda表達式上調用tpye()

>>> type(lambda:1)

<type 'function'>


查看 UDF 名字:

>>> foo.__name__

'foo'

>>> lambdaFunc.__name__

'<lambda>'


14.1.2 方法


14.3 內建方法(BIM)屬性:

BIM屬性描述

bim__doc__文檔字串

bim.__name__字符串類型的函數名字

bim.__self__綁定的對象


內建方法(BIMs)


提供一個內建方法來訪問BIM:


>>> type([].append)    

<type 'builtin_function_or_method'>


通過內建函數dir()來獲得他們的數據和方法屬性:

>>> dir([].append)

['__call__', '__class__', '__cmp__', '__delattr__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__name__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__self__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__']


用戶定義的方法(UDM)


>>> class C(object):# 定義類

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

...

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

>>> type(C)# 類的類別

<type 'type'>

>>> type(c)# 實例的類別

<class '__main__.C'>

>>> type(C.foo)# 非綁定方法的類別

<type 'instancemethod'>

>>> type(c.foo)# 綁定方法的類別

<type 'instancemethod'>


綁定的方法揭示了方法綁定到哪一個實例:


>>> C.foo# 非綁定方法對象

<unbound method C.foo>

>>> c.foo#綁定方法對象

<bound method C.foo of <__main__.C object at 0x7fc8d3d77790>>

>>> c# foo()實例被綁定到....

<__main__.C object at 0x7fc8d3d77790>


用戶自定義屬性


UDM屬性描述

udm__doc__文檔字符串(與udm.im_fuc.__doc__相同)

udm.__name__字符串類型的方法名字(與 umd.im_func.__name__相同)

udm.__module__定義udm模塊名(或none)

udm.im_class方法相關聯的類

udm.im_func方法的函數對象

udm.im_self如果綁定的話爲相關聯的實例,如果非綁定爲none


14.1.3 類


我們可以利用類的可調用行來創建實例,實例化調用的任何參數都會傳入到構造函數裏


>>> class C(object):

...   def __init__(self, *args):

...     print 'Instantiated with these arguments:\n', args

...

>>> c1 = C()

Instantiated with these arguments:

()

>>> c2 = C('The number of the counting shall be', 3)

Instantiated with these arguments:

('The number of the counting shall be', 3)


14.1.4 類的實例:


>>> class C(object):                                  

...   def __call__(self,*args):                      

...     print "I'm callable! Called with args:\n",args

...

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

>>> c# 我們的實例

<__main__.C object at 0x7fc8d3d77950>

>>> callable(c)# 實例是可調用的

True

>>> c()# 調用實例

I'm callable! Called with args:

()

>>> c(3)# 呼叫時給一個參數

I'm callable! Called with args:

(3,)

>>> c(3,'no more,no less') # 呼叫時給兩個參數

I'm callable! Called with args:

(3, 'no more,no less')


只有定義類的時候實現了__call__方法,類的實例才能成爲可調用的



14.2 代碼對象


可調用對象,語句,賦值,表達式,模塊等這些代碼塊被成爲代碼對象


14.3 可執行的對象聲明和內建函數:


內建函數和語句描述

callable(obj)如果obj可調用,返回True,否則返回FALSE

compile(string.file,type) 從type類型中創建代碼對象,file是代碼存放的地方

eval(obj,glo-bals=globals(),locals=locals())

對obj進行求值,obj是已編譯爲代碼對象的表達式,或 是一個字符串表達式,可以i給出全局或者/和局部的名 字空間

exec obj執行obj,單一的python語句或者語句的集合

input(prompt='')等同於eval(raw_input(prompt="))


14.3.1 callable()


callable()是一個布爾函數,確定一個對象是否可以通過函數操作符()來調用


>>> callable(dir)#內建函數

True

>>> callable(1)#整數

False

>>> def foo(): pass

...

>>> callable(foo)#用戶自定義函數

True

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

False

>>> class C(object): pass

...

>>> callable(C)#類

True


14.3.2 compile()


cmplie()函數在運行時迅速生成代碼對象,然後用exec語句或者內建函數eval()來執行這些對象或者對他們進行求值


compile三個參數都必須:

1.代表要編譯的Python代碼

2.字符串,存放代碼對象文件名,通常爲空

3.字符串,有三個可能值

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 <module> at 0x7fc8d3dcaf30, file "", line 1>

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


14.3.3 eval()

eval()對表達式求值,後者可以爲字符串或內建函數complie()創建的預編譯代碼對象


>>> eval('932')

932

>>> int('932')

932


內建函數eval()接收引號內的字符串並把它作爲python表達式進行求值


內建函數int()接收代表整數的字符串並把它轉換成整數


當我們用純字符串表達式,兩者便不再相同:


>>> eval('100 + 200')

300

>>> int('100 + 200')

Traceback (most recent call last):

 File "<stdin>", line 1, in <module>

ValueError: invalid literal for int() with base 10: '100 + 200'


eval()接收一個字符串並把"100+200"作爲表達式求值,當進行整數加法後給出返回值300

int()不能接收字符串等非法文字


14.3.4 exec

和eval()相似,exec語句執行代碼對象或字符串形式的python代碼,exec語句只接受一個參數,以下是通用語法

exec obj


例:

>>> 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文件對象,我們把上面的代碼寫入xcount.py文件:


# vi xcount.py

-----------------------------

#!/usr/bin/env python


exec """

x = 0

print 'x is currently:', x

while x < 5:

 x += 1

 print 'incrementing x to:', x

 """

-------------------------------


>>> f = open('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


14.3 可執行對象語句和內建函數:

一旦執行完畢,繼續對exec調用就會失敗,因爲exec已從文件中讀取了全部數據並停留在文件末尾,當用相同對象調用exec,便沒有可執行代碼,所以什麼也不做


用tell()查看文件身在何處,然後用os.path.getsize()獲取腳本大小,兩個數字完全一樣

>>> f.tell()# 我們文件在什麼地方

125

>>> f.close()# 關閉文件

>>> from os.path import getsize

>>> getsize('xcount.py')#文件有多大

125


使用seek()可到文件最開頭再次調用exec


>>> f = open('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


14.3.5 input()


內建函數input()是eval()和raw_input()的組合,等價於eval(raw_input())

類似於raw_input(), input()有一個可選參數,該參數代表了給用戶的字符串提示,不給定該字符串默認爲空


raw_input()以字符串形式,逐字返回用戶的輸入,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()把輸入作爲python對象來求值並返回表達式結果

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

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

>>> aList

[123, 'xyz', 45.67]

>>> type(aList)

<type 'list'>


14.3.6 使用Python在運行時生成和執行Python代碼


例1,動態聲稱和執行Python代碼:

# vi loopmake.py

-----------------------------------------------

#!/usr/bin/env python


dashes = '\n' + '-' * 50 #50個'-'號(開頭換行)


#構造一個存儲代碼的字典(不同的鍵對應不同的代碼),裏面變量均用佔位符,注意縮進

exec_dict = {

   'f': """ #for loop

for %s in %s:

   print %s

""",


   's': """ #sequence while loop

%s = 0

%s = %s

while %s < len(%s):

   print %s[%s]

   %s = %s + 1

""",


   'n': """ #count while loop

%s = %d

while %s < %d

   print %s

   %s = %s + %d

"""

}


def main():

   #以下是輸入用戶選擇的循環方式(for or while),以及操作的數據類型(數字或者序列)

   ltype = raw_input('Loop type? (For/While) ')

   dtype = raw_input('Data type? (Number/Seq) ')

   if dtype == 'n':    #表示選擇數字方式

       start = input('Starting value? ')

       stop = input('Ending value (non-inclusive)? ')

       step = input('Stepping value? ')

       seq = str(range(start, stop, step)) #產生數字序列

   else:

       seq = raw_input('Enter sequence: ') #表示選擇序列方式(需要輸入序列)


   var = raw_input('Iterative varible name? ') #輸入用於循環的變量名稱


   if ltype == 'f': #如果是for循環,則按照如下方式產生代碼

       #這種方式沒見過,給字典賦值,該複習字典了

       exec_str = exec_dict['f'] % (var, seq, var) #變量依次替換佔位符,直到用完

   elif ltype == 'w': #如果是while循環,則需要區分是哪種數據類型:如果是序列,我們需要提供一個序列的名稱(因爲while循環用到了len()來求序列長度,所以名字就必須了),否則就不用了

       if dtype == 's':

           svar = raw_input('Enter sequence name? ')

           exec_str = exec_dict['s'] % (var, svar, seq,\

                       var, svar, svar, var, var, var)

       elif dtype == 'n':

           exec_str = exec_dict['n'] % (var, start, var,\

                       stop, var, var, var, step)


   #下面就是相應的執行和測試

   print dashes

   print 'Your custom-generated code: ' + dashes

   print exec_str + dashes

   print 'Test execution of the code:' + dashes

   exec exec_str

   print dashes


if __name__ == "__main__":

   main()

------------------------------------


執行例子:


# python loopmake.py

Loop type? (For/While)f

Data type? (Number/Seq)n

Starting value?1

Ending value (non-inlusive)?22

Stepping value?2

Interative variable name?hehe


--------------------------------------------------

Your custom-generated code:

--------------------------------------------------


for hehe in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21]:

 print hehe


--------------------------------------------------

Test execution of the code:

--------------------------------------------------

1

3

5

7

9

11

13

15

17

19

21


--------------------------------------------------

root@ubuntu:~/python# python loopmake.py    

Loop type? (For/While)f

Data type? (Number/Seq)n

Starting value?0

Ending value (non-inlusive)?4

Stepping value?1

Interative variable name?counter


--------------------------------------------------

Your custom-generated code:

--------------------------------------------------


for counter in [0, 1, 2, 3]:

 print counter


--------------------------------------------------

Test execution of the code:

--------------------------------------------------

0

1

2

3


--------------------------------------------------

root@ubuntu:~/python# python loopmake.py

Loop type? (For/While)w

Data type? (Number/Seq)n

Starting value?0

Ending value (non-inlusive)?4

Stepping value?1

Interative variable name?counter


--------------------------------------------------

Your custom-generated code:

--------------------------------------------------


counter = 0

while counter < 4:

 print counter

 counter = counter + 1


--------------------------------------------------

Test execution of the code:

--------------------------------------------------

0

1

2

3


--------------------------------------------------


# python loopmake.py

Loop type? (For/While)f

Data type? (Number/Seq)s

Enter sequence: [932,'grail',3.0,'arrghhh']

Interative variable name?eachItem


--------------------------------------------------

Your custom-generated code:

--------------------------------------------------


for eachItem in [932,'grail',3.0,'arrghhh']:

 print eachItem


--------------------------------------------------

Test execution of the code:

--------------------------------------------------

932

grail

3.0

arrghhh


--------------------------------------------------


# python loopmake.py

Loop type? (For/While)w

Data type? (Number/Seq)s

Enter sequence: [932,'grail',3.0,'arrghhh']

Interative variable name?eachIndex

Enter sequence name?myList


--------------------------------------------------

Your custom-generated code:

--------------------------------------------------


eachIndex = 0

myList = [932,'grail',3.0,'arrghhh']

while eachIndex < len(myList):

 print myList[eachIndex]

 eachIndex = eachIndex + 1


--------------------------------------------------

Test execution of the code:

--------------------------------------------------

932

grail

3.0

arrghhh


--------------------------------------------------



有條件的執行代碼:


例14.2 調用sys.exit()使python解釋器退出,exit()的任何整數參數作爲退出狀態會返回給調用者,該值默認爲0


# vi funcAttrs.py    

----------------------------------

#!/usr/bin/env python


def foo():

   return True


def bar():

   'bar() does not do much'

   return True


foo.__doc__ = 'foo() does not do much'

foo.tester = """

if foo():

   print 'PASSED'

else:

   print 'FAILED'

"""


for eachAttr in dir():

   obj = eval(eachAttr)

   if isinstance(obj, type(foo)):

       if hasattr(obj, '__doc__'):

           print '\nFunction "%s" has a doc string:\n\t%s' \

            %(eachAttr,obj.__doc__)

       if hasattr(obj, 'tester'):

           print 'Function "%s" has a tester... executing' % eachAttr

           exec obj.tester

       else:

           print 'Function "%s" has no tester... skipping' % eachAttr

   else:

       print '"%s" is not a function' % eachAttr

-----------------------------------------

# python funcAttrs.py

-----------------------------------------

"__builtins__" is not a function

"__doc__" is not a function

"__file__" is not a function

"__name__" is not a function

"__package__" is not a function


Function "bar" has a doc string:

       bar() does not do much

Function "bar" has no tester... skipping


Function "foo" has a doc string:

       foo() does not do much

Function "foo" has a tester... executing

PASSED

-----------------------------------------


14.4 執行其他(Python)程序


14.4.1 導入


在運行時刻,有很多執行另外python腳本的方法,正如我們先前討論的,第一次導入模塊會執行模塊最高級的代碼,這就是python導入的行爲


核心筆記:當模塊導入後,就執行所有的模塊


# vi import1.py

--------------------------

#!/usr/bin/env python

print 'loaded import1'


import import2

--------------------------


# vi import2.py

--------------------------

#!/usr/bin/env python

print 'loaded import2'

--------------------------


這是我們導入import1時的輸出


>>> import import1

loaded import1

loaded import2


根據建議檢測__name__值的迂迴工作法,我們改變了import1.py和import2.py裏的


這裏是修改後的import.py版本:

# vi import1.py

--------------------------------

#!/usr/bin/env python

import import2


if __name__ == '__main__':

   print 'loaded import1'

--------------------------------


# vi import2.py

--------------------------

#!/usr/bin/env python

if __name__ == '__main__':

   print 'loaded import2'

--------------------------


當從python中導入import1時,我們避災會得到任何輸出


>>> import import1

>>>


這不意味在任何情況下都該這麼編寫代碼,某些情況你可能想要顯示輸出來確定輸入模塊,這取決於你自身情況,我們的目的是提供實效的編程例子來屏蔽副作用


14.4.2 execfile()


通過文件對象,使用exec語句來讀取python腳本的內容並執行

例:

f = open(filename,'r')

exec f

f.close


這三行可以調用execfile()來替換:

execfile(filename)


語法:

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


14.4.3 將模塊作爲腳本執行

你可以使用命令行從你的工作目錄中調用腳本

# myScript.py

或者

# python myScript.py


你想運行免費的python web服務器,以便創建和測試你自己的web頁面和cgi腳本,我們可以用python -c命令行開關:

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

---------------------------------------

Serving HTTP on 0.0.0.0 port 8000 ...

---------------------------------------


我們能夠在類庫中執行作爲腳本的模塊而不是作爲導入的模塊,這就是-m參數的動機,現在我們可以這樣運行腳本:

# python -m CGIHTTPServer

-----------------------------------------

Serving HTTP on 0.0.0.0 port 8000 ...

-----------------------------------------


14.4 執行其他(非Python)程序


在python程序裏我們可以執行非python程序,包括二進制可執行文件,其他shell腳本等


14.5.1 os.system()


system()接收字符串形式的系統命令並執行


>>> import os

>>> result = os.system('cat /etc/motd')

Welcome to Ubuntu 12.10 (GNU/Linux 3.5.0-17-generic x86_64)


* Documentation:  https://help.ubuntu.com/


 System information as of Tue Dec  3 14:14:54 CST 2013


 System load:  0.22               Processes:           76

 Usage of /:   27.2% of 18.56GB   Users logged in:     1

 Memory usage: 24%                IP address for eth0: 192.168.8.18

 Swap usage:   39%


 Graph this data and manage this system at https://landscape.canonical.com/


New release '13.04' available.

Run 'do-release-upgrade' to upgrade to it.


>>> result

0

>>> result = os.system('uname -a')

Linux ubuntu 3.5.0-17-generic #28-Ubuntu SMP Tue Oct 9 19:31:23 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux

>>> result

0


14.5.2 os.popen()


popen()函數式文件對象和sysem()函數的結合,工作方式和system()相同,但它可以建立一個指向那個程序的單向連接,然後如訪問一樣訪問這個程序


例,我們調用了unix程序uname來給我們提供系統相關信息,如果我們要吧字符串讀入變量中並執行內部操作或把它存儲到日誌文件,我們可以使用popen()


>>> import os

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

>>> data = f.readline()

>>> print data,

Linux ubuntu 3.5.0-17-generic #28-Ubuntu SMP Tue Oct 9 19:31:23 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux


popen()返回一個類文件對象;注意readlin()往往保留輸入文字行尾的newline字符


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


ret = os.fork()# 產生兩個進程,都返回

if ret == 0# 子進程返回的PID是0

 child_suite# 子進程的代碼

else:# 父進程返回時子進程的PID

 parent_suite# 父進程的代碼


ret = os.fork()

if ret == 0: #子進程代碼

 execvp('xbill', ['xbill'])

else:# 父進程代碼

 os.wait()


14.5.4 os.spawn*()


函數spawn*()家族和fork,exec*()相似,因爲他們在新進程中執行命令


14.5.5 subprocess模塊


替換os.system()

>>> from subprocess import call

>>> import os

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

Welcome to Ubuntu 12.10 (GNU/Linux 3.5.0-17-generic x86_64)


* Documentation:  https://help.ubuntu.com/


 System information as of Tue Dec  3 21:02:46 CST 2013


 System load:  0.0                Processes:           76

 Usage of /:   27.3% of 18.56GB   Users logged in:     1

 Memory usage: 25%                IP address for eth0: 192.168.8.18

 Swap usage:   39%


 Graph this data and manage this system at https://landscape.canonical.com/


New release '13.04' available.

Run 'do-release-upgrade' to upgrade to it.


>>> res

0


取代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 ubuntu 3.5.0-17-generic #28-Ubuntu SMP Tue Oct 9 19:31:23 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux

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

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

>>> f.close

<built-in method close of file object at 0x7ff689a7a660>

>>> for eachLine in data:

...   print eachLine

...

root     tty1         2013-12-03 00:33

root     pts/0        2013-12-03 21:02 (192.168.8.2)


14.5.6 相關函數


表14.7 各種文件執行函數:


文件對象 屬性描述

os/popen2.popen2*()執行文件,打開文件,從新創建的運行程序讀取(stdout),或者向該程序寫(stdin)

os/popen2.popen3*()執行文件,打開文件,從新創建的運行程序讀取(stdout和stder),或者向該程序寫(stdin)

os/popen2.popen4*()執行文件,打開文件,從新創建的運行程序讀取(stdout和stder),或者向該程序寫(stdin)

commends.getoutput()在子進程中執行文件,以祖父串返回所有的輸出

subprocess.call*()創建subprocess的便捷函數,Popen等待命令完成,然後返回狀態代碼,與os.system()類似,但是是較靈活的替代方案


14.6 受限執行


14.7 結束執行

當程序運行完成,所有模塊最高級的語句執行完畢後退出,我們便稱這是乾淨的執


14.7.1 sys.exit() and SystemExit

立刻退出程序並返回調用程序的主要方式是sys模塊中的exit()函數

sys.exit()語法爲:

system.exit(status=0)


例,調用sys.exit()使python解釋器退出,exit()的任何整數參數都會以退出狀態返回給調用者,該值默認爲0


# vi args.py

-------------------------------

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

-------------------------------


14.7.2 sys.exitfunc()


sys.exitfunc()默認是不可用的,但是你可以改寫他提供額外功能,當調用了sys.exit()並在解釋器退出之前,就會用到這個函數,這個函數不帶任何參數


下面例子介紹瞭如何設置exit()函數,如果已經被設置了,則確保執行該函數:


import sys

prev_exit_func = getattr(sys, 'exitfunc',None)

def my_exit_func(old_exit = prev_exit_func):

#:

# 進行清理

#:

if old_exit is not None and callable(old_exit):

   old_exit()


sys.exitfunc = my_exit_func


對getattr()的調用可以這麼寫:

if hasattr(sys, 'exitfunc'):

   prev_exit_func = sys.exitfunc

else:

   prev_exit_func = None


14,7.3 os._exit() Function os._exit()函數

語法:

os._exit(status)


這個函數提供的功能與sys.exit()和sys.exitfunc()相反,不執行任何清理便立即退出python


14.7.4 os.kill() Fonction

os模塊的kill()函數模擬傳統的unix函數來發送信號SIGINT,SIGQUIT,SIGKILL給進程使進程終結


14.8 各種操作系統接口


os模塊屬性描述

uname()獲得系統信息(主機名,操作系統版本,補丁級別,系統架構等等)

getuid()/setuid(uid)獲取/設置現在進程的真正的用戶ID

getpid()/getppid()獲取真正的現在/父進程ID(PID)

getgid()/setgid(gid)獲取/設置現在進程的羣組ID

getsid()/setsid()獲取會話ID(SID)或創建和返回新的SID

umask(mask)設置現在的數字unmask,同時返回先前的那個(mask用於文件許可)

getenv(ev)/

putenv(ev, value),

environ獲取和設置環境變量ev的值; os.envion屬性時描述當前所有環境變量的字典

......


14.9 相關模塊

......


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章