Exec中的挫折感了它
的Python 2.x的:
execfile("C:\\X\Y\\Z")
的Python 3+:
with open("C:\\X\Y\\Z", "r") as f:
exec(f.read())
不過,這是非常不好的做法 - 它從一個字符串(在某些時候)執行代碼,而不是使用導入模塊的優選和更安全的方式。但是,當您導入模塊並在「-f __name__ == '__main__'
:」之後輸入一些代碼時,這些部分將不起作用(因爲導入模塊中的__name__
不會是__main__
,並且如果將它作爲單個腳本運行)。
這是不好的原因是多方面的,在某種意義上強連接到Python的禪,但如果你是初學者,這應該對你說:
當你在交互模式下任何東西,你在一些工作命名空間(這個術語對理解python非常重要,如果你不知道它,請在python語言參考中檢查它)。當你沒有提供exec()
/execfile()
而沒有提供globals()
/locals()
時,最終可能會修改命名空間。
修改過的命名空間?
這是什麼意思?讓我們有一個這樣的腳本:
radius = 3
def field_of_circle(r):
return r*r*3.14
print(field_of_circle(radius))
現在,你有以下會議:
>>>radius = 5
>>>execfile("script_above.py")
28.26
>>>print(radius)
3
你看看會發生什麼?您在交互式會話中定義的變量將被腳本末尾的值覆蓋。修改已導入的外部模塊也是一樣。讓我們有一個非常簡單的模塊:
x = 1
並執行腳本:
import very_simple_module
very_simple_module.x = 3
現在,這裏有一個解釋器的交互會話:
>>>import very_simple_module
>>>print(very_simple_module.x)
1
>>>execfile("executed_script.py")
>>>print(very_simple_module.x)
3
運行另一個解釋
互動會議對許多人非常有用事情,但不是很多事情,但運行Python腳本不是其中之一。
除非......你想玩難以使用Python shell作爲系統外殼。然後,你可以使用子進程(標準庫)或sh(可發現on PyPI):
>>>import subprocess
>>>subprocess.call(["python", "C:\\X\Y\\Z"], shell=True)
>>>from sh import python
>>>python("C:\\X\Y\\Z")
那些不會有這個問題,修改交互式解釋命名空間
見腳本模塊
此外,還有一個選擇:在交互式會話中添加目錄與腳本PYTHONPATH,並命名爲腳本導入模塊:
>>>import sys
>>>if "C:\\X\\Y" not in sys.path:
sys.path.append("C:\\X\\Y")
>>>import Z
請記住,啓動解釋器的目錄會自動在pythonpath中,所以如果您已經在腳本所在的同一目錄中運行python,則只需使用上述第三行。
解釋器名稱空間不會更改,但「-f __name__ == '__main__'
:」之後的代碼將不會執行。仍然可以訪問腳本變量:
>>>radius = 5
>>>import first_example_script
>>>print(radius)
5
>>>print(first_example_script.radius)
3
此外,您可以有模塊名稱衝突。例如,如果你的腳本是sys.py,那麼這個解決方案就可以工作,因爲python會在你之前導入builtin sys
模塊。