Python是解釋型腳本語言,在執行時,逐句解釋執行,不需要進行預編譯。但需要有自身的Python解釋器。
所以在執行Python代碼時,需要指定python解釋器。
指定解釋器方法:
在文件開頭添加搜索路徑,
linux OS
中一般安裝後的默認路徑如下
#!/usr/bin/env python 或者#!/usr/locat/bin/python
如果沒有找到,可以通過命令查詢python路徑
whereis python或者
which python
Windows OS
可以通過以下方式查詢python路徑或者第三方模塊安裝路徑。
>>> import sys
>>> sys.path['C:\\Users\\zx\\Desktop', 'C:\\Users\\zx\\AppData\\Local\\Programs\\Python\\Python36-32\\lib\\site-packages']
cmd目錄下運行python -V可查看python版本
修改默認python版本
先查看安裝的python路徑:
justin18chan@justin18chan:~$ whereis python
python: /usr/bin/python /usr/bin/python3.5 /usr/bin/python2.7-config /usr/bin/python3.5m /usr/bin/python2.7 /usr/lib/python3.5 /usr/lib/python2.7 /etc/python /etc/python3.5 /etc/python2.7 /usr/local/bin/python3.6m-config /usr/local/bin/python3.6-config /usr/local/bin/python3.6m /usr/local/bin/python3.6 /usr/local/lib/python3.5 /usr/local/lib/python3.6 /usr/local/lib/python2.7 /usr/include/python3.5m /usr/include/python2.7 /usr/share/python /usr/share/man/man1/python.1.gz
使用ln -s命令來修改,命令如下:
justin18chan@justin18chan:~$ sudo rm /usr/bin/python
[sudo] password for justin18chan: justin18chan@justin18chan:~$ sudo ln -s /usr/bin/python3.5 /usr/bin/python
justin18chan@justin18chan:~$ pythonPython 3.5.2 (default, Sep 14 2017, 22:51:06)
Ⅱ 為什麼編譯的Python模塊,但不是腳本正在運行
文件是在導入編譯。 這不是一個安全的事情。 這僅僅是如果你將其導入蟒蛇保存輸出。 看到這個帖子由Fredrik Lundh開發上Effbot。
>>>import main
# main.pyc is created
當運行一個腳本巨蟒將不使用* .pyc文件的文件。 如果你有你想要你的腳本一些其他的原因,預編譯可以使用compileall模塊。
python -m compileall .
compileall用法
python -m compileall --help
option --help not recognized
usage: python compileall.py [-l] [-f] [-q] [-d destdir] [-x regexp] [directory ...]
-l: don't recurse down
-f: force rebuild even if timestamps are up-to-date
-q: quiet operation
-d destdir: purported directory name for error messages
if no directory arguments, -l sys.path is assumed
-x regexp: skip files matching the regular expression regexp
the regexp is searched for in the full path of the file
回答以下問題編輯
如果響應是潛在的磁碟許可權的目錄main.py,為什麼Python的編譯模塊?
模塊和腳本將被視為相同。 進口是什麼觸發要保存的輸出。
如果原因是好處將是最小的,可以考慮的情況時,該腳本將被用於大量的時間(諸如在一個CGI應用程序)。
使用compileall不解決這個問題。 由蟒蛇執行的腳本將不使用*.pyc,除非明確要求。 這有負面影響,深受格倫·梅納德在他的回答說。
CGI應用程序的給出的例子確實應該使用像FastCGI的技術來解決。 如果你想消除編譯腳本的開銷,可能要消除啟動蟒蛇太大,何況資料庫連接開銷的開銷。
光引導腳本可以用來甚至python -c "import script",但這些都值得商榷的風格。
格倫·梅納德提供一些靈感來糾正和改進這個答案。
似乎沒有人想這樣說,但我敢肯定的答案很簡單:有這種行為沒有堅實的理由。
所有到目前為止所提出的理由基本上是不正確的:
沒有什麼特別的主文件。 它作為一個模塊載入,並顯示了sys.moles像任何其他模塊。 運行主腳本無非就是用的模塊名稱導入更__main__。
有與沒有保存.pyc文件由於只讀目錄中的文件沒有問題; 蟒蛇簡單地忽略它,並在移動。
緩存腳本的好處是相同緩存任何模塊的:不浪費時間每次它的運行時間重新編譯腳本。 該文檔明確地承認這一點(「因此,腳本的啟動時間可能會減少......」)。
另一個問題需要注意:如果您運行python foo.py和foo.pyc存在,它不會被使用。你必須明確地說,python foo.pyc。 這是一個非常糟糕的主意:它意味著當它是不同步的Python不會自動重新編譯的.pyc文件的文件(由於.py文件變化),因此對.py文件的更改將不會使用,直到您手動重新編譯。 它也將與拋出一個RuntimeError徹底失敗如果升級的Python和.pyc文件的文件格式不再兼容,這經常發生。 通常情況下,這是所有透明地處理。
你不應該需要一個腳本移動到一個虛擬的模塊,並成立了引導腳本欺騙的Python到其高速緩存。 這是一個hackish的解決方法。
唯一可能(而且非常缺乏說服力)我之所以能湊合是避免從一堆pyc文件被雜亂的主目錄。 (這不是真正的理由;如果這是一個實際的問題,則pyc文件應保存為點文件)。這當然沒有理由不甚至有一個選項來做到這一點。
蟒絕對應該能夠緩存主模塊。
以來:
當它從.pyc文件或.pyo文件時,它是從一個.py文件閱讀不是閱讀程序不會跑得更快; 這是關於.pyc文件或.pyo文件的速度的唯一事情就是與它們載入速度。
這是不必要的,以產生用於主腳本pyc文件的文件。 只有那些可能會被載入多次圖書館應編制。
編輯:
這似乎你沒明白我的意思。 首先,認識到編制的整體思路.pyc文件也作出了同樣的文件在第二次執行速度更快。 然而,考慮是否做的Python編譯腳本正在運行。 解釋器將位元組碼寫入到一個.pyc的文件在第一次運行,這需要時間。 因此,它甚至會運行有點慢。 你可能會認為它會更快之後運行。 好吧,這只是一個選擇。 此外,作為this說:
明確優於隱式。
如果想通過使用加速.pyc的文件,應該手動編譯並運行.pyc明確文件。
要回答你的問題,參考6.1.3。 「編譯」Python文件在Python正式文件。
當腳本由命令行上給出它的名字運行,腳本的位元組碼不會被寫入一個.pyc文件或.pyo文件。 因此,腳本的啟動時間可通過移動它的大部分代碼的一個模塊,並具有導入這個模塊一小啟動腳本減少。 另外,也可以命名.pyc文件或直接.pyo文件的命令行上。
教育學
讓我又愛又恨類似這樣的問題上如此,因為有感情,意見的復雜混合物,和受過教育的猜測事情,人們開始變得snippy,不知何故每個人都失去了賽道的實際情況,最終失去了軌道原題的共。
這么多的技術問題都至少有一個明確的答案,但這些「為什麼」的問題往往沒有隻是一個單一的,確定的答案(例如,可以通過執行或引用權威人士的答案來驗證答案)。 在我看來,有兩個可能的方式來明確回答計算機科學「為什麼」的問題:
通過指向一個實現所關注的項目的源代碼。 這就解釋了「為什麼」從技術角度來看:什麼前提條件是必要的,以喚起這種行為?
通過指向人類可讀的文物(注釋,提交信息,郵件列表等)由參與作出該決定的開發人員編寫的。 這就是「為什麼」,我假設OP是感興趣的真正意義:為什麼Python的開發人員使這種看似隨意的決定?
第二種回答是更加難以證實,因為它需要獲得在誰寫的代碼開發者的心,特別是如果沒有容易找到,公開文件中的特定行為的決定。
迄今為止,這個討論有7回答是只專注於閱讀的Python的開發者的意圖,但只有一個在整批引用。 (它引用了不回答OP的問題了Python手冊的部分。)
這是我在與沿引用既回答了「為什麼」的問題兩側的嘗試。
源代碼
什麼是觸發.pyc文件編制的前提條件? 讓我們來看看源代碼。 (煩人,在GitHub上Python沒有發布任何標記,所以我就告訴你,我在尋找715a6e)。
有在希望的代碼import.c:989在load_source_mole()函數。 我在這里切出一些位為簡潔起見。
static PyObject *
load_source_mole(char *name, char *pathname, FILE *fp)
{
// snip...
if (/* Can we read a .pyc file? */) {
/* Then use the .pyc file. */
}
else {
co = parse_source_mole(pathname, fp);
if (co == NULL)
return NULL;
if (Py_VerboseFlag)
PySys_WriteStderr("import %s # from %s
",
name, pathname);
if (cpathname) {
PyObject *ro = PySys_GetObject("dont_write_bytecode");
if (ro == NULL || !PyObject_IsTrue(ro))
write_compiled_mole(co, cpathname, &st);
}
}
m = PyImport_ExecCodeMoleEx(name, (PyObject *)co, pathname);
Py_DECREF(co);
return m;
}
pathname是路徑模塊和cpathname是相同的路徑,但是用pyc文件擴展名。 唯一的直接邏輯是布爾sys.dont_write_bytecode。 邏輯的其餘部分就是錯誤處理。 因此,我們所尋求的答案不在這里,但我們至少可以看到,調用此的任何代碼將導致在大多數默認配置的.pyc文件的文件。 該parse_source_mole()函數沒有真正意義要執行的流程,但我會在這里顯示,因為我會回來稍後。
static PyCodeObject *
parse_source_mole(const char *pathname, FILE *fp)
{
PyCodeObject *co = NULL;
mod_ty mod;
PyCompilerFlags flags;
PyArena *arena = PyArena_New();
if (arena == NULL)
return NULL;
flags.cf_flags = 0;
mod = PyParser_ASTFromFile(fp, pathname, Py_file_input, 0, 0, &flags,
NULL, arena);
if (mod) {
co = PyAST_Compile(mod, pathname, NULL, arena);
}
PyArena_Free(arena);
return co;
}
這里的顯著的方面是,函數解析和編譯的文件,並返回一個指針的位元組代碼(如果成功)。
現在,我們仍處於一個死胡同,讓我們處理這個從一個新的角度。 如何Python中載入它的參數,並執行它? 在pythonrun.c有用於從文件載入代碼並執行它的幾個功能。PyRun_AnyFileExFlags()可以處理互動式和非互動式的文件描述符。 對於互動式的文件描述符,它委託給PyRun_InteractiveLoopFlags()這是REPL)和非互動式的文件描述符,它委託給PyRun_SimpleFileExFlags()PyRun_SimpleFileExFlags()檢查文件名 中結束.pyc。 如果這樣做的話,就調用run_pyc_file()直接載入編譯位元組碼從一個文件描述符然後運行它。
在更常見的情況下(即.py文件作為參數),PyRun_SimpleFileExFlags()調用PyRun_FileExFlags()這是我們開始找到了答案。
PyObject *
PyRun_FileExFlags(FILE *fp, const char *filename, int start, PyObject *globals,
PyObject *locals, int closeit, PyCompilerFlags *flags)
{
PyObject *ret;
mod_ty mod;
PyArena *arena = PyArena_New();
if (arena == NULL)
return NULL;
mod = PyParser_ASTFromFile(fp, filename, start, 0, 0,
flags, NULL, arena);
if (closeit)
fclose(fp);
if (mod == NULL) {
PyArena_Free(arena);
return NULL;
}
ret = run_mod(mod, filename, globals, locals, flags, arena);
PyArena_Free(arena);
return ret;
}
static PyObject *
run_mod(mod_ty mod, const char *filename, PyObject *globals, PyObject *locals,
PyCompilerFlags *flags, PyArena *arena)
{
PyCodeObject *co;
PyObject *v;
co = PyAST_Compile(mod, filename, flags, arena);
if (co == NULL)
return NULL;
v = PyEval_EvalCode(co, globals, locals);
Py_DECREF(co);
return v;
}
這里的突出的一點是,這兩個函數基本上執行相同的目的,進口商的load_source_mole()和parse_source_mole()它調用解析器創建從Python源代碼的AST,然後調用編譯器創建位元組碼。
那麼,這些代碼塊多餘的還是他們的目的不同? 不同的是,一個塊載入從文件的模塊,而其他塊使用的是模塊作為參數。該模塊的說法是-在這種情況下-在__main__模塊,它使用的是低級別的C函數早些時候在初始化過程中創建的。 該__main__模塊不通過最正常的模塊導入代碼路徑,因為它是如此獨特,並且作為一個副作用,它不通過產生代碼去.pyc的文件。
總結:為什麼原因__main__。模塊未編譯.pyc文件是它是不是「進口」是的,它出現在sys.moles中,但它通過不是真正的模塊導入採取了非常不同的代碼路徑到達那裡。
開發者意圖
好了,我們現在可以看到的行為更多的是與Python的設計比在源代碼中任何明確表達的理由,但是這並沒有回答這是否是一種有意的決定,或只是一個副作用的問題這不打擾任何人足以成為值得改變。 一個開源的好處是,一旦我們發現我們感興趣的源代碼,我們可以使用VCS幫助追溯,導致目前實施的決定。
其中代碼的關鍵行這里(m = PyImport_AddMole("__main__");)的歷史可以追溯到1990年,並在自己BDFL,圭多寫的。 它已被修改,在干預的歲月,但修改是膚淺的。 當它第一次寫,一個腳本參數主模塊初始化是這樣的:
int
run_script(fp, filename)
FILE *fp;
char *filename;
{
object *m, *d, *v;
m = add_mole("`__main__`");
if (m == NULL)
return -1;
d = getmoledict(m);
v = run_file(fp, filename, file_input, d, d);
flushline();
if (v == NULL) {
print_error();
return -1;
}
DECREF(v);
return 0;
}
這之前存在.pyc的文件甚至被引入到Python的! 難怪當時的設計沒有考慮匯編成賬戶腳本參數。 提交信息神秘地說:
「編譯」版本
這是幾十的一個承諾,在3天的時間......看來,圭多是深入到一些黑客/重構,這是一回到是穩定的第一個版本。 這種承諾甚至五年左右早於Python的開發郵件列表的創建!
保存編譯的位元組碼引入以後6個月,於1991年。
這仍然早於列表服務,所以我們有一個什麼樣圭多想沒有真正的想法。 看來,他只是認為,進口商為掛接到緩存位元組碼的目的,最好的地方。 他是否考慮做同樣為理念__main__不清:要麼沒有想到他,不然他認為這是更多的麻煩比它的價值。
我無法找到要緩存為主要模塊的位元組碼相關的bugs.python.org任何錯誤,也可以找到關於它的郵件列表上的任何消息,因此,顯然沒有人認為這是值得的麻煩嘗試添加它。
總結:為什麼所有模塊編譯的緣故.pyc除了__main__是,它是歷史的怪癖如何設計和實現。__main__被作品烤成代碼前.pyc的文件,即使存在。 如果你想知道的多的是,你需要電子郵件圭多和要求。
格倫·梅納德的回答說:
似乎沒有人想這樣說,但我敢肯定的答案很簡單:有這種行為沒有堅實的理由。
我同意100%。 有間接證據來支持這一理論,沒有人在這個線程別人提供的證據來支持任何其他理論的一個切絲。 我upvoted格倫的回答。
因為劇本正在運行可能會在某處是不恰當的生成pyc文件,如/usr/bin。
Ⅲ python項目代碼變更後一定要重新編譯嗎
一般的時候,你直接用py文件執行就可以了,python會自動編譯一些必要的文件。
另外目前py不同的位元組碼是變動的,也就是說不同版本的位元組碼還是不兼容,做不動一次編譯到處執行。
如果你現在三個文件 main.py, a.py, b.py
其中main是入口,而且在main中有import a.py 和import b.py
那麼只會生成a.pyc,b.pyc,而不會生成main.pyc
出發你自己用python中的compile命令編譯main.py
以上
Ⅳ python是什麼樣的編程語言
編程語言主要從以下幾個角度為進行分類,編譯型和解釋型、靜態語言和動態語言、強類型定義語言和弱類型定義語言,每個分類代表什麼意思呢,我們一起來看一下。
2.1 編譯型與解釋型。
編譯器是把源程序的每一條語句都編譯成機器語言,並保存成二進制文件,這樣運行時計算機可以直接以機器語言來運行此程序,速度很快;
而解釋器則是只在執行程序時,才一條一條的解釋成機器語言給計算機來執行,所以運行速度是不如編譯後的程序運行的快的.
這是因為計算機不能直接認識並執行我們寫的語句,它只能認識機器語言(是二進制的形式)
編譯型
優點:編譯器一般會有預編譯的過程對代碼進行優化。因為編譯只做一次,運行時不需要編譯,所以編譯型語言的程序執行效率高。可以脫離語言環境獨立運行。
缺點:編譯之後如果需要修改就需要整個模塊重新編譯。編譯的時候根據對應的運行環境生成機器碼,不同的操作系統之間移植就會有問題,需要根據運行的操作系統環境編
解釋型
優點:有良好的平台兼容性,在任何環境中都可以運行,前提是安裝了解釋器(虛擬機)。靈活,修改代碼的時候直接修改就可以,可以快速部署,不用停機維護。
缺點:每次運行的時候都要解釋一遍,性能上不如編譯型語言。
2.2動態語言和靜態語言
通常我們所說的動態語言、靜態語言是指動態類型語言和靜態類型語言。
(1)動態類型語言:動態類型語言是指在運行期間才去做數據類型檢查的語言,也就是說,在用動態類型的語言編程時,永遠也不用給任何變數指定數據類型,該語言會在你第一次賦值給變數時,在內部將數據類型記錄下來。Python和Ruby就是一種典型的動態類型語言,其他的各種腳本語言如VBScript也多少屬於動態類型語言。
(2)靜態類型語言:靜態類型語言與動態類型語言剛好相反,它的數據類型是在編譯其間檢查的,也就是說在寫程序時要聲明所有變數的數據類型,C/C++是靜態類型語言的典型代表,其他的靜態類型語言還有C#、java等。
2.3強類型定義語言和弱類型定義語言
(1)強類型定義語言:強制數據類型定義的語言。也就是說,一旦一個變數被指定了某個數據類型,如果不經過強制轉換,那麼它就永遠是這個數據類型了。舉個例子:如果你定義了一個整型變數a,那麼程序根本不可能將a當作字元串類型處理。強類型定義語言是類型安全的語言。
(2)弱類型定義語言:數據類型可以被忽略的語言。它與強類型定義語言相反, 一個變數可以賦不同數據類型的值。
強類型定義語言在速度上可能略遜色於弱類型定義語言,但是強類型定義語言帶來的嚴謹性能夠有效的避免許多錯誤。另外,"這門語言是不是動態語言」與"這門語言是否類型安全」之間是完全沒有聯系的!
例如:Python是動態語言,是強類型定義語言(類型安全的語言); VBScript是動態語言,是弱類型定義語言(類型不安全的語言); JAVA是靜態語言,是強類型定義語言(類型安全的語言)。
通過上面這些介紹,我們可以得出,python是一門動態解釋性的強類型定義語言。
Ⅳ Java,Python分別是解釋型還是編譯型語言
Java,Python都是解釋型的,但是java會做一個語法檢查的預編譯,執行的時候才解釋成機器語言。
C、C++才是編譯型的
解釋型的通用性好,可以跨平台
編譯型的效率高。
Ⅵ python 有沒有預編譯文本
1.簡介
相對於py文件來說,編譯成pyc和pyo本質上和py沒有太大區別,只是對於這個模塊的載入速度提高了,並沒有提高代碼的執行速度,通常情況下不用主動去編譯pyc文件,除非需要商業提供,防止源代碼泄露。
(1)什麼是pyc文件
pyc是一種二進制文件,是由py文件經過編譯後,生成的文件,是一種byte code,py文件變成pyc文件後,載入的速度有所提高,而且pyc是一種跨平台的位元組碼,是由Python的虛擬機來執行的,這個是類似於Java虛擬機的概念。pyc的內容,是跟python的版本相關的,不同版本編譯後的pyc文件是不同的,2.5編譯的pyc文件,2.4版本的python是無法執行的。
(2)什麼是pyo文件
pyo是優化編譯後的程序 python -O 源文件即可將源程序編譯為pyo文件
把需要的模塊編譯成pyo文件可以減少容量
2.反編譯
將python文件編譯為pyc文件(使用compileall 命令),再刪除源代碼。
(該文件類似於java中的class文件,但是我們使用的2.7版本的python,目前沒有
免費版的反編譯工具,所以目前要破解不是很容易,所以可以不必再做混淆)
(1)命令行編譯方法:
python -m compileall src/
echo compile finished...
rm -rf src/*.py
編譯成pyo的話:
就是在控制台執行 python -O -m py_compile file.py
(2)python程序編譯方法:
如果需要特殊的單獨編譯,則只需要使用py_complie這個模塊就行了,如下
import py_compile
py_compile.compile(r'H:\game\test.py')
反編譯工具:
1.uncompyle2 只能編譯2.7
反編譯Demo代碼:
import os
import sys
def displayFile(file):
unPath= sys.executable
unPath=unPath[ 0 : unPath.rfind( os.sep ) ]
newname = file[0:file.rfind('.')] + '.py'
command = "python -u "+unPath+"\scripts\uncompyle2 " + file + ">" + newname
try:
os.system(command)
except e:
print file
if __name__ == '__main__':
#print unPath
print 'init'
displayFile('E:\\test.pyc')
print 'finished'
2.zrax/pycdc 可以編譯3.0
Ⅶ python代碼運行需要編譯嗎
有人在討論 Python 代碼是編譯執行還是解釋執行?這個問題還可以換一種說法: Python 是編譯型語言還是解釋型語言?回答這個問題
前,我們先弄清楚什麼是編譯型語言,什麼是解釋型語言。
所謂編譯執行就是源代碼經過編譯器編譯處理,生成目標機器碼,就是機器能直接運行的二進制代碼,下次運行時無需重新編譯。不過它
是針對特定CPU體系的,這些目標代碼只能在特定平台執行,如果這個程序需要在另外一種 CPU 上面運行,這個代碼就必須重新編譯。
它不具備可移植性,但是執行速度快,C、C++這類語言屬於編譯型語言。
而解釋型語言是在代碼運行期間逐行翻譯成目標機器碼,下次執行時,還是需要逐行解釋,我們可以簡單認為 Java、Python 都是解釋型
語言。
編譯型相當於廚師直接做好一桌子菜,顧客來了直接開吃,而解釋型就像吃火鍋,廚師把菜洗好,顧客需要自己動手邊煮邊吃,效率上來
說解釋型語言自然比不過編譯型語言,當然也不是絕對了,像 JIT 的效率就很高
以上是對編譯型語言和解釋型語言的一個簡單粗暴的區分,但是 Python(這里主要是指CPython)並不是嚴格的解釋型語言,因為
Python 代碼在運行前,會先編譯(翻譯)成中間代碼,每個 .py 文件將被換轉成 .pyc 文件,.pyc 就是一種位元組碼文件,它是與平台無
關的中間代碼,不管你放在 Windows 還是 Linux 平台都可以執行,運行時將由虛擬機逐行把位元組碼翻譯成目標代碼。
我們安裝Python 時候,會有一個 Python.exe 文件,它就是 Python 解釋器,你寫的每一行 Python 代碼都是由它負責執行,解釋器由
一個編譯器和一個虛擬機構成,編譯器負責將源代碼轉換成位元組碼文件,而虛擬機負責執行位元組碼,所以,解釋型語言其實也有編譯過
程,只不過這個編譯過程並不是直接生成目標代碼,而是中間代碼(位元組碼),然後再通過虛擬機來逐行解釋執行位元組碼。
總結
Python代碼首先會編程一個位元組碼文件,再由虛擬機逐行解釋,把每一行位元組碼代碼翻譯成目標指令給CPU執行。
推薦學習《Python教程》。
Ⅷ Python代碼是編譯執行還是解釋執行
PYTHON是一種解釋型的腳本語言,所以是解釋執行的