pyc文件是怎么創(chuàng)建的?
前面我們提到,每一個(gè)代碼塊(code block)都會(huì)對(duì)應(yīng)一個(gè)PyCodeObject對(duì)象,Python會(huì)將該對(duì)象存儲(chǔ)在pyc文件中。但不幸的是,事實(shí)并不總是這樣。有時(shí),當(dāng)我們運(yùn)行一個(gè)簡單的程序時(shí)并沒有產(chǎn)生pyc文件,因此我們猜測:有些Python程序只是臨時(shí)完成一些瑣碎的工作,這樣的程序僅僅只會(huì)運(yùn)行一次,然后就不會(huì)再使用了,因此也就沒有保存至pyc文件的必要。
如果我們?cè)诖a中加上了一個(gè)import abc這樣的語句,再執(zhí)行你就會(huì)發(fā)現(xiàn)Python為其生成了pyc文件,這就說明import會(huì)觸發(fā)pyc的生成。
實(shí)際上,在運(yùn)行過程中,如果碰到import abc這樣的語句,那么Python會(huì)在設(shè)定好的path中尋找abc.pyc或者abc.pyd文件。如果沒有這些文件,而是只發(fā)現(xiàn)了abc.py,那么Python會(huì)先將abc.py編譯成PyCodeObject,然后創(chuàng)建pyc文件,并將PyCodeObject寫到pyc文件里面去。
接下來,再對(duì)abc.pyc進(jìn)行import動(dòng)作,對(duì),并不是編譯成PyCodeObject對(duì)象之后就直接使用。而是先寫到pyc文件里面去,然后再將pyc文件里面的PyCodeObject對(duì)象重新在內(nèi)存中復(fù)制出來。
關(guān)于Python的import機(jī)制,我們后面會(huì)剖析,這里只是用來完成pyc文件的觸發(fā)。當(dāng)然得到pyc文件還有其它方法,比如使用py_compile模塊。
#a.pyclassA:a=1#b.pyimporta執(zhí)行b.py的時(shí)候,會(huì)發(fā)現(xiàn)創(chuàng)建了a.cpython-38.pyc。另外關(guān)于pyc文件的創(chuàng)建位置,會(huì)在當(dāng)前文件的同級(jí)目錄下的__pycache__目錄中創(chuàng)建,名字就叫做:py文件名.cpython-版本號(hào).pyc。
pyc文件里面包含哪些內(nèi)容上面我們提到,Python通過import module進(jìn)行加載時(shí),如果沒有找到相應(yīng)的pyc或者pyd文件,就會(huì)在py文件的基礎(chǔ)上自動(dòng)創(chuàng)建pyc文件。而創(chuàng)建之后,會(huì)往里面寫入三個(gè)內(nèi)容:
1. magic number
這是Python定義的一個(gè)整數(shù)值,不同版本的Python會(huì)定義不同的magic number,這個(gè)值是為了保證Python能夠加載正確的pyc。
比如Python3.7不會(huì)加載3.6版本的pyc,因?yàn)镻ython在加載pyc文件的時(shí)候會(huì)首先檢測該pyc的magic number,如果和自身的magic number不一致,則拒絕加載。
2. pyc的創(chuàng)建時(shí)間
這個(gè)很好理解,判斷源代碼的最后修改時(shí)間和pyc文件的創(chuàng)建時(shí)間。如果pyc文件的創(chuàng)建時(shí)間比源代碼的修改時(shí)間要早,說明在生成pyc之后,源代碼被修改了,那么會(huì)重新編譯并生成新的pyc,而反之則會(huì)直接加載已存在的pyc。
3. PyCodeObject對(duì)象
這個(gè)不用說了,肯定是要存儲(chǔ)的。
pyc文件的寫入下面就來看看pyc文件是如何寫入上面三個(gè)內(nèi)容的。
既然要寫入,那么肯定要有文件句柄,我們來看看:
//位置:Python/marshal.c//FILE是C自帶的文件句柄//可以把WFILE看成是FILE的包裝typedefstruct{FILE*fp;//文件句柄//下面的字段在寫入信息的時(shí)候會(huì)看到interror;intdepth;PyObject*str;char*ptr;char*end;char*buf;_Py_hashtable_t*hashtable;intversion;}WFILE;首先是寫入magic number和創(chuàng)建時(shí)間,它們會(huì)調(diào)用PyMarshal_WriteLongToFile函數(shù)進(jìn)行寫入:
voidPyMarshal_WriteLongToFile(longx,FILE*fp,intversion){//magicnumber和創(chuàng)建時(shí)間,只是一個(gè)整數(shù)//在寫入的時(shí)候,使用char[4]來保存charbuf[4];//聲明一個(gè)WFILE類型變量wfWFILEwf;//內(nèi)存初始化memset(&wf,0,sizeof(wf));//初始化內(nèi)部成員wf.fp=fp;wf.ptr=wf.buf=buf;wf.end=wf.ptr+sizeof(buf);wf.error=WFERR_OK;wf.version=version;//調(diào)用w_long將x、也就是版本信息或者時(shí)間寫到wf里面去w_long(x,&wf);//刷到磁盤上w_flush(&wf);}所以該函數(shù)只是初始化了一個(gè)WFILE對(duì)象,真正寫入則是調(diào)用的w_long。
staticvoidw_long(longx,WFILE*p){w_byte((char)(x&0xff),p);w_byte((char)((x>>8)&0xff),p);w_byte((char)((x>>16)&0xff),p);w_byte((char)((x>>24)&0xff),p);}w_long則是調(diào)用 w_byte 將 x 逐個(gè)字節(jié)地寫到文件里面去。
而寫入PyCodeObject對(duì)象則是調(diào)用了PyMarshal_WriteObjectToFile,我們也來看看長什么樣子。
voidPyMarshal_WriteObjectToFile(PyObject*x,FILE*fp,intversion){charbuf[BUFSIZ];WFILEwf;memset(&wf,0,sizeof(wf));wf.fp=fp;wf.ptr=wf.buf=buf;wf.end=wf.ptr+sizeof(buf);wf.error=WFERR_OK;wf.version=version;if(w_init_refs(&wf,version))return;/*callermushcheckPyErr_Occurred()*/w_object(x,&wf);w_clear_refs(&wf);w_flush(&wf);}可以看到和PyMarshal_WriteLongToFile基本是類似的,只不過在實(shí)際寫入的時(shí)候,PyMarshal_WriteLongToFile調(diào)用的是w_long,而PyMarshal_WriteObjectToFile調(diào)用的是w_object。
staticvoidw_object(PyObject*v,WFILE*p){charflag='\0';p->depth++;if(p->depth>MAX_MARSHAL_STACK_DEPTH){p->error=WFERR_NESTEDTOODEEP;}elseif(v==NULL){w_byte(TYPE_NULL,p);}elseif(v==Py_None){w_byte(TYPE_NONE,p);}elseif(v==PyExc_StopIteration){w_byte(TYPE_STOPITER,p);}elseif(v==Py_Ellipsis){w_byte(TYPE_ELLIPSIS,p);}elseif(v==Py_False){w_byte(TYPE_FALSE,p);}elseif(v==Py_True){w_byte(TYPE_TRUE,p);}elseif(!w_ref(v,&flag,p))w_complex_object(v,flag,p);p->depth--;}可以看到本質(zhì)上還是調(diào)用了w_byte,但這僅僅是一些特殊的對(duì)象。如果是列表、字典之類的數(shù)據(jù),那么會(huì)調(diào)用w_complex_object,也就是代碼中的最后一個(gè)else if分支。
w_complex_object這個(gè)函數(shù)的源代碼很長,我們看一下整體結(jié)構(gòu),具體邏輯就不貼了,我們后面會(huì)單獨(dú)截取一部分進(jìn)行分析。
staticvoidw_complex_object(PyObject*v,charflag,WFILE*p){Py_ssize_ti,n;//如果是整數(shù)的話,執(zhí)行整數(shù)的寫入邏輯if(PyLong_CheckExact(v)){//......}//如果是浮點(diǎn)數(shù)的話,執(zhí)行浮點(diǎn)數(shù)的寫入邏輯elseif(PyFloat_CheckExact(v)){if(p->version>1){//......}else{//......}}//如果是復(fù)數(shù)的話,執(zhí)行復(fù)數(shù)的寫入邏輯elseif(PyComplex_CheckExact(v)){if(p->version>1){//......}else{//......}}//如果是字節(jié)序列的話,執(zhí)行字節(jié)序列的寫入邏輯elseif(PyBytes_CheckExact(v)){//......}//如果是字符串的話,執(zhí)行字符串的寫入邏輯elseif(PyUnicode_CheckExact(v)){if(p->version>=4&&PyUnicode_IS_ASCII(v)){//......}else{//......}}else{//......}}//如果是元組的話,執(zhí)行元組的寫入邏輯elseif(PyTuple_CheckExact(v)){//......}//如果是列表的話,執(zhí)行列表的寫入邏輯elseif(PyList_CheckExact(v)){//......}//如果是字典的話,執(zhí)行字典的寫入邏輯elseif(PyDict_CheckExact(v)){//......}//如果是集合的話,執(zhí)行集合的寫入邏輯elseif(PyAnySet_CheckExact(v)){//......}//如果是PyCodeObject對(duì)象的話//執(zhí)行PyCodeObject對(duì)象的寫入邏輯elseif(PyCode_Check(v)){//......}//如果是Buffer的話,執(zhí)行Buffer的寫入邏輯elseif(PyObject_CheckBuffer(v)){//......}else{W_TYPE(TYPE_UNKNOWN,p);p->error=WFERR_UNMARSHALLABLE;}}源代碼雖然長,但是邏輯非常單純,就是對(duì)不同的對(duì)象、執(zhí)行不同的寫動(dòng)作,然而其最終目的都是通過w_byte寫到pyc文件中。了解完函數(shù)的整體結(jié)構(gòu)之后,我們?cè)倏匆幌戮唧w細(xì)節(jié),看看它在寫入對(duì)象的時(shí)候到底寫入了哪些內(nèi)容?
staticvoidw_complex_object(PyObject*v,charflag,WFILE*p){//......elseif(PyList_CheckExact(v)){W_TYPE(TYPE_LIST,p);n=PyList_GET_SIZE(v);W_SIZE(n,p);for(i=0;i<n;i++){w_object(PyList_GET_ITEM(v,i),p);}}elseif(PyDict_CheckExact(v)){Py_ssize_tpos;PyObject*key,*value;W_TYPE(TYPE_DICT,p);/*ThisoneisNULLobjectterminated!*/pos=0;while(PyDict_Next(v,&pos,&key,&value)){w_object(key,p);w_object(value,p);}w_object((PyObject*)NULL,p);}//......}以列表和字典為例,它們?cè)趯懭氲臅r(shí)候?qū)嶋H上寫的是內(nèi)部的元素,其它對(duì)象也是類似的。
deffoo():lst=[1,2,3]#把列表內(nèi)的元素寫進(jìn)去了print(foo.__code__.co_consts)#(None,1,2,3)但問題來了,如果只是寫入元素的話,那么Python在加載的時(shí)候怎么知道它是一個(gè)列表呢?所以在寫入的時(shí)候不能光寫數(shù)據(jù),類型信息也要寫進(jìn)去。我們?cè)倏匆幌律厦媪斜砗妥值涞膶懭脒壿嫞锩娑颊{(diào)用了W_TYPE,它負(fù)責(zé)將類型信息寫進(jìn)去。
因此無論對(duì)于哪種對(duì)象,在寫入具體數(shù)據(jù)之前,都會(huì)先調(diào)用W_TYPE將類型信息寫進(jìn)去。如果沒有類型信息,那么當(dāng)Python加載pyc文件的時(shí)候,只會(huì)得到一坨字節(jié)流,而無法解析字節(jié)流中隱藏的結(jié)構(gòu)和蘊(yùn)含的信息。
所以在往pyc文件里寫入數(shù)據(jù)之前,必須先寫入一個(gè)標(biāo)識(shí),諸如TYPE_LIST、TYPE_TUPLE、TYPE_DICT等等,這些標(biāo)識(shí)正是對(duì)應(yīng)的類型信息。
如果解釋器在pyc文件中發(fā)現(xiàn)了這樣的標(biāo)識(shí),則預(yù)示著上一個(gè)對(duì)象結(jié)束,新的對(duì)象開始,并且也知道新對(duì)象是什么樣的對(duì)象,從而也知道該執(zhí)行什么樣的構(gòu)建動(dòng)作。當(dāng)然,這些標(biāo)識(shí)也是可以看到的,在底層已經(jīng)定義好了。
//marshal.c#defineTYPE_NULL'0'#defineTYPE_NONE'N'#defineTYPE_FALSE'F'#defineTYPE_TRUE'T'#defineTYPE_STOPITER'S'#defineTYPE_ELLIPSIS'.'#defineTYPE_INT'i'/*TYPE_INT64isnotgeneratedanymore.Supportedforbackwardcompatibilityonly.*/#defineTYPE_INT64'I'#defineTYPE_FLOAT'f'#defineTYPE_BINARY_FLOAT'g'#defineTYPE_COMPLEX'x'#defineTYPE_BINARY_COMPLEX'y'#defineTYPE_LONG'l'#defineTYPE_STRING's'#defineTYPE_INTERNED't'#defineTYPE_REF'r'#defineTYPE_TUPLE'('#defineTYPE_LIST'['#defineTYPE_DICT'{'#defineTYPE_CODE'c'#defineTYPE_UNICODE'u'#defineTYPE_UNKNOWN'?'#defineTYPE_SET'<'#defineTYPE_FROZENSET'>'到了這里可以看到,其實(shí)Python對(duì)PyCodeObject對(duì)象的導(dǎo)出實(shí)際上是不復(fù)雜的。因?yàn)椴还苁裁磳?duì)象,最后都為歸結(jié)為兩種簡單的形式,一種是數(shù)值寫入,一種是字符串寫入。
上面都是對(duì)數(shù)值的寫入,比較簡單,僅僅需要按照字節(jié)依次寫入pyc即可。然而在寫入字符串的時(shí)候,Python設(shè)計(jì)了一種比較復(fù)雜的機(jī)制,有興趣可以自己閱讀源碼,這里不再介紹。
PyCodeObject的包含關(guān)系有下面一個(gè)文件:
//位置:Python/marshal.c//FILE是C自帶的文件句柄//可以把WFILE看成是FILE的包裝typedefstruct{FILE*fp;//文件句柄//下面的字段在寫入信息的時(shí)候會(huì)看到interror;intdepth;PyObject*str;char*ptr;char*end;char*buf;_Py_hashtable_t*hashtable;intversion;}WFILE;0顯然編譯之后會(huì)創(chuàng)建三個(gè)PyCodeObject對(duì)象,但是有兩個(gè)PyCodeObject對(duì)象是位于另一個(gè)PyCodeObject對(duì)象當(dāng)中的。
也就是foo和A對(duì)應(yīng)的PyCodeObject對(duì)象,位于模塊對(duì)應(yīng)的PyCodeObject對(duì)象當(dāng)中,準(zhǔn)確的說是位于co_consts指向的常量池當(dāng)中。舉個(gè)栗子:
//位置:Python/marshal.c//FILE是C自帶的文件句柄//可以把WFILE看成是FILE的包裝typedefstruct{FILE*fp;//文件句柄//下面的字段在寫入信息的時(shí)候會(huì)看到interror;intdepth;PyObject*str;char*ptr;char*end;char*buf;_Py_hashtable_t*hashtable;intversion;}WFILE;1我們看到f2對(duì)應(yīng)的PyCodeObject確實(shí)位于f1的常量池當(dāng)中,準(zhǔn)確的說是f1的常量池中有一個(gè)指針指向f2對(duì)應(yīng)的PyCodeObject。
不過這都不是重點(diǎn),重點(diǎn)是PyCodeObject對(duì)象是可以嵌套的。當(dāng)在一個(gè)作用域內(nèi)部發(fā)現(xiàn)了一個(gè)新的作用域,那么新的作用域?qū)?yīng)的PyCodeObject對(duì)象會(huì)位于外層作用域的PyCodeObject對(duì)象的常量池中,或者說被常量池中的一個(gè)指針指向。
而在寫入pyc的時(shí)候會(huì)從最外層、也就是模塊的PyCodeObject對(duì)象開始寫入。如果碰到了包含的另一個(gè)PyCodeObject對(duì)象,那么就會(huì)遞歸地執(zhí)行寫入新的PyCodeObject對(duì)象。
如此下去,最終所有的PyCodeObject對(duì)象都會(huì)寫入到pyc文件當(dāng)中。因此pyc文件里的PyCodeObject對(duì)象也是以一種嵌套的關(guān)系聯(lián)系在一起的,和代碼塊之間的關(guān)系是保持一致的。
//位置:Python/marshal.c//FILE是C自帶的文件句柄//可以把WFILE看成是FILE的包裝typedefstruct{FILE*fp;//文件句柄//下面的字段在寫入信息的時(shí)候會(huì)看到interror;intdepth;PyObject*str;char*ptr;char*end;char*buf;_Py_hashtable_t*hashtable;intversion;}WFILE;2這里問一下,上面那段代碼中創(chuàng)建了幾個(gè)PyCodeObject對(duì)象呢?
答案是6個(gè),首先模塊是一個(gè),foo函數(shù)一個(gè),bar函數(shù)一個(gè),類A一個(gè),類A里面的foo函數(shù)一個(gè),類A里面的bar函數(shù)一個(gè),所以一共是6個(gè)。
而且這里的PyCodeObject對(duì)象是層層嵌套的,一開始是對(duì)整個(gè)全局模塊創(chuàng)建PyCodeObject對(duì)象,然后遇到了函數(shù)foo,那么再為函數(shù)foo創(chuàng)建PyCodeObject對(duì)象,依次往下。
所以,如果是常量值,則相當(dāng)于是靜態(tài)信息,直接存儲(chǔ)起來便可。可如果是函數(shù)、類,那么會(huì)為其創(chuàng)建新的PyCodeObject對(duì)象,然后再收集起來。
小結(jié)以上就是pyc文件相關(guān)的內(nèi)容,源文件在編譯之后會(huì)得到pyc文件。因此我們不光可以手動(dòng)導(dǎo)入 pyc,用Python直接執(zhí)行pyc文件也是可以的。
以上就是本次分享的所有內(nèi)容,想要了解更多歡迎前往公眾號(hào):Python編程學(xué)習(xí)圈,每日干貨分享
執(zhí)行標(biāo)準(zhǔn)以Q開頭的有什么區(qū)別?
執(zhí)行標(biāo)準(zhǔn)以Q開頭并不差。這種編號(hào)方式代表的是企業(yè)標(biāo)準(zhǔn),它規(guī)定了企業(yè)在生產(chǎn)、經(jīng)營和管理等方面的一系列要求。企業(yè)標(biāo)準(zhǔn)是企業(yè)內(nèi)部規(guī)范行為的文件,其重要性在于確保企業(yè)活動(dòng)的有序性和產(chǎn)品的質(zhì)量。國家鼓勵(lì)企業(yè)制定高于國家標(biāo)準(zhǔn)或行業(yè)標(biāo)準(zhǔn)的企業(yè)標(biāo)準(zhǔn),以此來推動(dòng)企業(yè)的技術(shù)進(jìn)步和管理提升。企業(yè)標(biāo)準(zhǔn)的制定和發(fā)布...
nx10每次拆分體時(shí)選YC-ZC時(shí)怎么默認(rèn)偏置為0
打開模板文件,把里面的裝夾偏置改為1保存就可以了。由于幾個(gè)模板都有默認(rèn)的坐標(biāo)創(chuàng)建出來,所以幾個(gè)模板文件的裝夾都改掉。
UG加工怎么設(shè)置坐標(biāo)系
中“csys”對(duì)話框,選擇“自動(dòng)判斷”,鼠標(biāo)點(diǎn)擊模型文件表面,設(shè)置模型文件中心位置坐標(biāo)系,點(diǎn)擊確定,回到MCS對(duì)話框。4、點(diǎn)開安全平面選項(xiàng),選擇“刨”,設(shè)置距平面安全距離為10.mm,點(diǎn)擊完成,完成安全平面的設(shè)置。5、點(diǎn)開“WORKPIECE”選項(xiàng),設(shè)置幾何體的部件和毛坯,點(diǎn)擊確定,完成坐標(biāo)系的完全創(chuàng)建。
怎么將cass里的高程點(diǎn)生成坐標(biāo)文件
提取原有地形圖圖面上的坐標(biāo)和高程點(diǎn):“工程應(yīng)用菜單”-“圖面高程點(diǎn)生成數(shù)據(jù)文件”或“等高線生成 數(shù)據(jù)文件”獲取原圖中的坐標(biāo)高程數(shù)據(jù),并保存為CASS的dat坐標(biāo)數(shù)據(jù)文件。
.yc后綴的文件用什么播放器可以播放
這是洋蔥數(shù)學(xué)的視頻,洋蔥花了幾百萬加的格式,這個(gè)暫時(shí)對(duì)于小成本或者0成本還是無解的。
yccard.dll丟失怎么回事
2、文件損壞:yccard.dll文件可能由于磁盤故障、病毒感染等原因而損壞。3、注冊(cè)表錯(cuò)誤:yccard.dll文件的相關(guān)信息可能在Windows注冊(cè)表中存在錯(cuò)誤或損壞。4、軟件沖突或版本不匹配:某些軟件或驅(qū)動(dòng)程序依賴于特定版本的yccard.dll文件,如果您安裝了不兼容的軟件或版本,就可能導(dǎo)致yccard.dll丟失的錯(cuò)誤。
UG編程建立連接件三維模型,實(shí)例!
步驟1:新建圖形文件 在UG中,點(diǎn)擊【新建】,選擇【模型】文件類型,命名為“7-1.prt”。設(shè)定單位為【毫米】,然后點(diǎn)擊【創(chuàng)建】,進(jìn)入【建模】模塊。實(shí)體建模 通過【插入】|【草圖】命令,選擇YC-ZC平面作為工作平面,點(diǎn)擊【確定】,開始繪制草圖。按照要求繪制草圖后,點(diǎn)擊【完成】并退出草圖模式。創(chuàng)建...
怎么找病毒子文件,急
對(duì)于已經(jīng)判斷是病毒文件的“Winion0n.exe”文件,通過搜索“本地所有分區(qū)”、“搜索系統(tǒng)文件夾和隱藏的文件和文件夾”,找到該文件的藏身之所,將它刪除。 不過這樣刪除的只是病毒主文件,通過查看它的屬性,依據(jù)它的文件創(chuàng)建曰期、大小再次進(jìn)行搜索,找出它的同伙并刪除。 如果你不確定還有那些文件是它的親戚,通過網(wǎng)絡(luò)搜...
GO語言無縫地圖游戲服務(wù)端YCServer源碼解析(2)
UserManager服務(wù)專注于玩家管理,接收玩家連接,記錄玩家所在地圖服務(wù)和當(dāng)前地圖切換狀態(tài)。相關(guān)數(shù)據(jù)結(jié)構(gòu)位于UserInfo.go文件中,包括YEntity.Info(玩家實(shí)體信息)、M_uid(玩家ID)、M_current_map(當(dāng)前地圖服務(wù))、M_session_id(網(wǎng)絡(luò)連接標(biāo)識(shí))、M_map_switch_state(地圖切換狀態(tài))等。YCServer的實(shí)體結(jié)構(gòu)...
YC進(jìn)入中國第一批項(xiàng)目:超級(jí)簡歷WonderCV
今年,YC決定進(jìn)入中國,不僅在清華舉辦了300名創(chuàng)業(yè)者的Startup School盛會(huì),還邀請(qǐng)了前百度總裁兼COO陸奇,成為Y Combinator中國創(chuàng)始人兼CEO。作為YC進(jìn)入中國錄取的第一批項(xiàng)目,超級(jí)簡歷WonderCV是一個(gè)由本土團(tuán)隊(duì)創(chuàng)立、服務(wù)國內(nèi)用戶的高速發(fā)展初創(chuàng)公司。它的目標(biāo)是通過人工智能技術(shù)幫助用戶在求職過程中取得成功,找到理想的工作...
相關(guān)評(píng)說:
疏附縣起始: ______ pyc文件是py文件編譯后生成的字節(jié)碼文件(byte code).pyc文件經(jīng)過python解釋器最終會(huì)生成機(jī)器碼運(yùn)行.所以pyc文件是可以跨平臺(tái)部署的,類似Java的.class文件.一般py文件改變后,都會(huì)重新生成pyc文件.
疏附縣起始: ______ 單獨(dú)寫一個(gè)python文件,假設(shè)命名為comp.py,內(nèi)容如下: 1 2 importpy_compile py_compile.compile(r'路徑du\ASA.py') 代碼中“路徑”修改為你放asa.py的文件路徑,然后執(zhí)行comp.py,會(huì)在目錄下生成名字為__pycache__的文件夾,pyc文件就在此文件內(nèi).
疏附縣起始: ______ 在Python 中引用是非常簡單的事情,這里需要清楚三個(gè)概念就可以了包、模塊、類.類這個(gè)就不用說了. 模塊對(duì)應(yīng)的是一個(gè).py 文件,那么module_name 就是這個(gè)文件去掉.py 之后的文件名,py 文件中可以直接定義一些變量、函數(shù)、類. 那么...
疏附縣起始: ______ python文件為xxxxx.py 編譯過后為xxxx.pyc 當(dāng)然python工程也可以編譯為 exe可執(zhí)行程序
疏附縣起始: ______ 實(shí)際上python 是腳本語言解釋執(zhí)行的,并不存在編譯這個(gè)概念. 用 python -m py_compile file.py python -m py_compile {file1,file2}.py 編譯成pyc文件. pyc是一種二進(jìn)制文件,是由py文件經(jīng)過編譯后,生成的文件,是一種byte code,py文件變成pyc...
疏附縣起始: ______ import之后重命名: 如:a 和 b 中都有 同名的 xxx 函數(shù),導(dǎo)入之后 分別重命名為 name_1、name_2 from a import xxx as name_1 from b import xxx as name_2
疏附縣起始: ______ 你好:pyc文件是可以自動(dòng)生成的;如果有py文件的話;
疏附縣起始: ______ python源文件后綴名是.py,編譯后的后綴名是.pyc 編譯的話,直接python.exe foo.py就可以啊,不過你要注意的python.exe環(huán)境變量的設(shè)置.創(chuàng)建python目錄?不太明白你的意思,操作系統(tǒng)里直接新建不就ok了?或者你意思說python的包?如果這樣,在目錄里新建一個(gè)__init__.py就可以了
疏附縣起始: ______ 問題定位:查看import庫的源文件,發(fā)現(xiàn)源文件存在且沒有錯(cuò)誤,同時(shí)存在源文件的.pyc文件問題解決方法:命名py腳本時(shí),不要與python預(yù)留字,模塊名等相同.刪除該庫的.pyc文件(因?yàn)閜y腳本每次運(yùn)行時(shí)均會(huì)生成.pyc文件;在已經(jīng)生成.pyc...
疏附縣起始: ______ 很奇怪樓主為什么要打開pyc文件,pyc是二進(jìn)制文件,所以你用記事本打開它的時(shí)候只會(huì)看到亂碼. py文件作為模塊被import的時(shí)候,python為了提高解析速度,對(duì)所有這些作為模塊的py文件先作一個(gè)類似編譯的動(dòng)作,產(chǎn)生相應(yīng)的pyc文件.這樣當(dāng)有別的程序再次import這些模塊時(shí),python就不用再重新解析py文件,而是讀入pyc文件就可以了 如果你打開pyc文件是為了想看源代碼,那建議你去找回相對(duì)應(yīng)的py文件