python指令碼的兩種調用方式__python

來源:互聯網
上載者:User

1、python指令碼中經常第一句出現#!/usr/bin/env python或#!/usr/bin/python。這句話的意義下面解釋:

指令碼語言的第一行,目的就是指出,你想要你的這個檔案中的代碼用什麼可執行程式去運行它,就這麼簡單

#!/usr/bin/python是告訴作業系統執行這個指令碼的時候,調用/usr/bin下的python解譯器;
#!/usr/bin/env python這種用法是為了防止作業系統使用者沒有將python裝在預設的/usr/bin路徑裡。當系統看到這一行的時候,首先會到env設定裡尋找python的安裝路徑,再調用對應路徑下的解譯器程式完成操作。
#!/usr/bin/python相當於寫死了python路徑;
#!/usr/bin/env python會去環境設定尋找python目錄,推薦這種寫法

如果你用 python xxoo.py 來運行,那麼寫不寫都沒關係,如果要用 ./xxoo.py 那麼就必須加這行, 用來為指令碼語言指定解譯器.

通常認為用 #!/usr/bin/env python 要比 #!/usr/bin/python 更好,因為 python 解譯器有時並不安裝在預設路徑,例如在 virtualenv 中。

  當你把py檔案直接賦予執行許可權去執行 ./yourfile.py 的時候,給檔案指定一個解譯器。

而 #!/usr/bin/python 是一般預設的python解譯器的路徑,所以這種的就是裝在預設位置的不會出問題。

但是 #!/usr/bin/envpython 則更加通用一些會去你的PATH 中尋找python 。

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

python指令碼的兩種調用方式說明:

1、./run.py.shell直接調用python指令碼

2、python run.py 調用python 解譯器來調用python指令碼

 

先分別解釋:

1、./run.py呼叫指令碼的方式。shell把run.py當成一般的指令碼看待,不把它當成python指令碼。按這種方式呼叫指令碼,python 指令碼的第一行必須有:

#!/usr/bin/env python3(或#!/usr/bin/env python)

先舉例子說明,在說明原因:

未加#!/usr/bin/env python3的情況:

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

a.py:

print ('a')

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

說明:要使用./a.py,必須使用chmod將a.py的屬性改成可執行檔。       

chmod 755 a.py

-rwxr-xr-x 1 root root   12 Nov 27 09:43 a.py

如果a.py是不可執行檔,那麼./a.py就會報如下錯誤。

-bash: ./a.py: Permissiondenied

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

在將a.py改為可執行後,如果使用./a.py,還是會報錯。

./a.py: line 1: syntaxerror near unexpected token `'a''

./a.py: line 1: `print('a')'

但是,因為我系統中裝了python2和python3.

所以,使用#!/usr/bin/env python3提示shell使用python3來呼叫指令碼.

a.py內容如下:---------------------------------------------------------------------------------------------------

#!/usr/bin/env python3

print ('a')

執行結果為:a

 

python3 print函數必須要加上().

所以,如果上述的print('a')變為print 'a',顯然是會報錯的。

root@iZ28yi4s6zwZ:/mnt/DisplayAdvertisingChallenge/Gbdt_Fm_Kaggle#./a.py

  File "./a.py", line 2

    print 'a'

            ^

SyntaxError: invalidsyntax

以上就說明了,使用./run.py調用python指令碼的方式,取決於你在python指令碼中第一句,並且使用./run.py必須在指令檔中寫上#!/usr/bin/env python3(或類似的命令),不然都執行不了。

1、先說明一下,我的系統中是預裝了python2,然後我裝了python3,並且系統預設的python是python2。我裝了python3並沒有改變系統預設的python解譯器,也不建議把系統預設的python解譯器改變了,因為像scikit-learn等庫很多還是基於python2.7的,你把系統預設的python改成python3會導致很多庫出問題。

2、看一下/usr/bin:就知道在ubuntu中,各種軟體的安裝情況

lrwxrwxrwx 1 root   root         9 Jun 19  2013 python -> python2.7

lrwxrwxrwx 1 root   root         9 Jun 19  2013 python2 -> python2.7

-rwxr-xr-x 1 root   root   2985296 Dec 19  2014 python2.7

lrwxrwxrwx 1 root   root        30 Nov 26 10:08 python3 ->/opt/python3.3.2/bin/python3.3

說明:

1、python-> python2.7:系統預設的python是python2.7

2、python2-> python2.7:python2執行的是python2.7

3、python3-> /opt/python3.3.2/bin/python3.3:python3執行的是/opt/python3.3.2/bin/python3.3

 

現在做個實驗:說明使用./run.py的方式,隨著第一句#!/usr/bin/envpython3的不同,shell會調用不同的python解譯器。

1、

#!/usr/bin/env python3import subprocess, sys, os, timeNR_THREAD = 1start = time.time()cmd = 'converters/pre-a.py trainsample0.25.csv tr.gbdt.dense tr.gbdt.sparse'subprocess.call(cmd, shell=True)cmd = 'converters/pre-a.py testsample0.25.csv te.gbdt.dense te.gbdt.sparse'subprocess.call(cmd, shell=True)print ("end pre-a.py")

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

中斷程式查看shell調用哪個python解譯器:

File"./run_test.py", line 10, in <module>

    subprocess.call(cmd, shell=True)

  File "/opt/python3.3.2/lib/python3.3/subprocess.py", line 522, incall

Traceback (most recentcall last):

  File "converters/pre-a.py", line36, in <module>

    key = field + '-' + row[field]

KeyboardInterrupt

    return p.wait(timeout=timeout)

  File "/opt/python3.3.2/lib/python3.3/subprocess.py", line 1528,in wait

    (pid, sts) = self._try_wait(0)

  File "/opt/python3.3.2/lib/python3.3/subprocess.py", line 1485,in _try_wait

    (pid, sts) = _eintr_retry_call(os.waitpid,self.pid, wait_flags)

  File "/opt/python3.3.2/lib/python3.3/subprocess.py", line 476, in_eintr_retry_call

    return func(*args)

KeyboardInterrupt

很明顯,使用#!/usr/bin/env python3,那麼shell就調用了python3的解譯器。

 

2、

 

#!/usr/bin/env python2import subprocess, sys, os, timeNR_THREAD = 1start = time.time()cmd = 'converters/pre-a.py trainsample0.25.csv tr.gbdt.dense tr.gbdt.sparse'subprocess.call(cmd, shell=True)cmd = 'converters/pre-a.py testsample0.25.csv te.gbdt.dense te.gbdt.sparse'subprocess.call(cmd, shell=True)print ("end pre-a.py")

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

中斷程式查看shell調用哪個python解譯器:

Traceback (most recentcall last):

  File "./run_test.py", line 10, in<module>

    subprocess.call(cmd, shell=True)

  File "/usr/lib/python2.7/subprocess.py",line 493, in call

    return Popen(*popenargs, **kwargs).wait()

  File "/usr/lib/python2.7/subprocess.py",line 1291, in wait

    pid, sts = _eintr_retry_call(os.waitpid,self.pid, 0)

  File "/usr/lib/python2.7/subprocess.py",line 478, in _eintr_retry_call

    return func(*args)

KeyboardInterrupt

很明顯,使用#!/usr/bin/env python2,那麼shell就調用了python2的解譯器。

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

3、

 

#!/usr/bin/env pythonimport subprocess, sys, os, timeNR_THREAD = 1start = time.time()cmd = 'converters/pre-a.py trainsample0.25.csv tr.gbdt.dense tr.gbdt.sparse'subprocess.call(cmd, shell=True)cmd = 'converters/pre-a.py testsample0.25.csv te.gbdt.dense te.gbdt.sparse'subprocess.call(cmd, shell=True)

print ("endpre-a.py")

中斷程式查看shell調用哪個python解譯器:

  File"./run_test.py", line 10, in <module>

    subprocess.call(cmd, shell=True)

  File "/usr/lib/python2.7/subprocess.py",line 493, in call

    return Popen(*popenargs, **kwargs).wait()

  File "/usr/lib/python2.7/subprocess.py",line 1291, in wait

    pid, sts = _eintr_retry_call(os.waitpid,self.pid, 0)

  File "/usr/lib/python2.7/subprocess.py",line 478, in _eintr_retry_call

    return func(*args)

KeyboardInterrupt

root@iZ28yi4s6zwZ:/mnt/DisplayAdvertisingChallenge/Gbdt_Fm_Kaggle#Traceback (most recent call last):

  File "converters/pre-a.py", line19, in <module>

    for row incsv.DictReader(open(args['csv_path'])):

  File "/opt/python3.3.2/lib/python3.3/csv.py", line 118, in__next__

    d = dict(zip(self.fieldnames, row))

KeyboardInterrupt

很明顯,使用#!/usr/bin/env python,那麼shell就調用了系統預設的python解譯器,也就是python2。python -> python2.7。那麼,為什麼還會出現python3.3.2。那是因為程式中,subprocess.call(cmd, shell=True),開了一個子進程,使用了shell來調用pre-a.py,pre-a.py肯定是使用#!/usr/bin/envpython3

.pre-a.py指令碼的內容如下:

#!/usr/bin/env python3import argparse, csv, sysfrom common import *if len(sys.argv) == 1:    sys.argv.append('-h')parser = argparse.ArgumentParser()parser.add_argument('csv_path', type=str)parser.add_argument('dense_path', type=str)parser.add_argument('sparse_path', type=str)args = vars(parser.parse_args())

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

2、如果使用python run.py 的方式來呼叫指令碼,那麼指令檔中的第一句#!/usr/bin/envpython3就會被自動略掉,不會起到任何的作用。

python2 run.py代表使用預設的python2解譯器來呼叫指令碼。

python3 run.py 代表使用預設的python3解譯器來呼叫指令碼。

python run.py 代表使用預設的python解譯器來呼叫指令碼。

 

python run_test.py:

^CTraceback (mostrecent call last):

  File "run_test.py", line 10, in<module>

    subprocess.call(cmd, shell=True)

  File "/usr/lib/python2.7/subprocess.py",line 493, in call

    return Popen(*popenargs, **kwargs).wait()

  File "/usr/lib/python2.7/subprocess.py",line 1291, in wait

    pid, sts = _eintr_retry_call(os.waitpid,self.pid, 0)

  File "/usr/lib/python2.7/subprocess.py",line 478, in _eintr_retry_call

    return func(*args)

KeyboardInterrupt

root@iZ28yi4s6zwZ:/mnt/DisplayAdvertisingChallenge/Gbdt_Fm_Kaggle#Traceback (most recent call last):

  File "converters/pre-a.py", line22, in <module>

    val = row['I{0}'.format(j)]

KeyboardInterrupt

很明顯,python run_test.py,使用預設的python解譯器(python2)來呼叫指令碼。

 

python3 run_test.py:

^CTraceback (mostrecent call last):

  File "run_test.py", line 10, in<module>

    subprocess.call(cmd, shell=True)

  File "/opt/python3.3.2/lib/python3.3/subprocess.py", line 522, in call

    return p.wait(timeout=timeout)

  File "/opt/python3.3.2/lib/python3.3/subprocess.py", line 1528, in wait

    (pid, sts) = self._try_wait(0)

  File "/opt/python3.3.2/lib/python3.3/subprocess.py", line 1485, in _try_wait

    (pid, sts) = _eintr_retry_call(os.waitpid,self.pid, wait_flags)

  File "/opt/python3.3.2/lib/python3.3/subprocess.py", line 476, in _eintr_retry_call

    return func(*args)

KeyboardInterrupt

root@iZ28yi4s6zwZ:/mnt/DisplayAdvertisingChallenge/Gbdt_Fm_Kaggle#Traceback (most recent call last):

  File "converters/pre-a.py", line19, in <module>

    for row incsv.DictReader(open(args['csv_path'])):

  File "/opt/python3.3.2/lib/python3.3/csv.py", line 118, in __next__

    d = dict(zip(self.fieldnames, row))

KeyboardInterrupt

很明顯,python3 run_test.py,使用python3解譯器來呼叫指令碼。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.