简明Python教程学习笔记_3_模块
模塊
如果你想要在其他程序中重用很多函數,那么你該如何編寫程序呢?你可能已經猜到了,答案是使用模塊。模塊基本上就是一個包含了所有你定義的函數和變量的文件。為了在其他程序中重用模塊,模塊的文件名必須以.py為擴展名。
python有三種導入模塊的方法
其一,
import modname : 模塊是指一個可以交互使用,或者從另一Python 程序訪問的代碼段。只要導入了一個模塊,就可以引用它的任何公共的函數、類或屬性。模塊可以通過這種方法來使用其它模塊的功能。
用import語句導入模塊,就在當前的名稱空間(namespace)建立了一個到該模塊的引用.這種引用必須使用全稱,也就是說,當使用在被導入模塊中定義的函數時,必須包含模塊的名字。所以不能只使用 funcname,而應該使用 modname.funcname
其二,
from modname import funcname
from modname import fa, fb, fc
或者 from modname import *
與第1種方法的區別:funcname 被直接導入到本地名字空間去了,所以它可以直接使用,而不需要加上模塊名的限定
* 表示,該模塊的所有公共對象(public objects)都被導入到 當前的名稱空間,也就是任何只要不是以”_”開始的東西都會被導入。
modname沒有被定義,所以modname.funcname這種方式不起作用。并且,如果funcname如果已經被定義,它會被新版本(該導入模塊中的版本)所替代。如果funcname被改成指向其他對象,modname不能不會覺察到。
建議:
1)如果你要經常訪問模塊的屬性和方法,且不想一遍又一遍地敲入模塊名,使用 from module import
2)如果你想要有選擇地導入某些屬性和方法,而不想要其它的,使用 from module import
3)如果模塊包含的屬性和方法與你的某個模塊同名,你必須使用import module來避免名字沖突
4)盡量少用 from module import * ,因為判定一個特殊的函數或屬性是從哪來的有些困難,并且會造成調試和重構都更困難。
其三
內建函數__import__()
除了前面兩種使用import關鍵字的方法以外,我們還可以使用內建函數 __import__() 來導入 module。兩者的區別是,import 后面跟的必須是一個類型(type),而__import__() 的參數是一個字符串,這個字符串可能來自配置文件,也可能是某個表達式計算結果。例如
mymodule = __import__ (’module_name’)
附注:
1)模塊的內容都放在一個模塊文件中,如 mymodule 的內容應該放在PYTHONPATH 目錄下的一個mymodule.py中,C實現的除外
2)包可以將幾個模塊名稱空間組織起來, 如A.b 就表示在包A中的一個子模塊b
可以單獨導入某一個子模塊,如Python文檔中給出的例子
import sound.effects.echo
這樣必須使用全稱對里面的對象進行引用,如
sound.effects.echo.echofilter(input, output, delay=0.7, atten=4)
還可以使用下面的語句來加載echo子模塊
from Sound.Effects import echo
它在沒有包前綴的情況下也可以使用, 所以它可以如下方式調用:
echo.echofilter(input, output, delay=0.7, atten=4)
不主張從一個包或模塊中用import * 導入所有模塊,因為這樣的通常會導致可讀性很差。
from Package import specific_submodule的用法并沒有錯,實際上這還是推薦的用法,除非導入的模塊需要使用其它包中的同名子模塊(the importing module needs to use submodules with the same name from different packages).
綜上所述,一般情況應該使用import , 但有幾個例外
1)module文檔告訴你要用from-import的
2)導入一個包組件。需要一個包里面的某個子模塊,一般用from A.b import c比import A.b.c 更方便 且不會冒混淆的危險.
使用模塊
#!/usr/bin/python # Filename: using_sys.py import sys print 'The command line arguments are:' for i in sys.argv:print i print '\n\nThe PYTHONPATH is',sys.path,'\n'在Python中用關鍵字import來引入某個模塊,比如要引用模塊math,就可以在文件最開始的地方用import math來引入。在調用math模塊中的函數時,必須這樣引用:
模塊名.函數名
為什么必須加上模塊名這樣調用呢?因為可能存在這樣一種情況:在多個模塊中含有相同名稱的函數,此時如果只是通過函數名來調用,解釋器無法知道到底要調用哪個函數。所以如果像上述這樣引入模塊的時候,調用函數必須加上模塊名。
有時候我們只需要用到模塊中的某個函數,只需要引入該函數即可,此時可以通過語句
from 模塊名 import 函數名1,函數名2....
當然可以通過不僅僅可以引入函數,還可以引入一些常量。通過這種方式引入的時候,調用函數時只能給出函數名,不能給出模塊名,但是當兩個模塊中含有相同名稱函數的時候,后面一次引入會覆蓋前一次引入。也就是說假如模塊A中有函數function( ),在模塊B中也有函數function( ),如果引入A中的function在先、B中的function在后,那么當調用function函數的時候,是去執行模塊B中的function函數。 如果想一次性引入math中所有的東西,還可以通過from math import *來實現,但是不建議這么做。
Python本身就內置了很多非常有用的模塊,只要安裝完畢,這些模塊就可以立刻使用。以內建的sys模塊為例,編寫一個hello的模塊:
import sys
導入sys模塊后,我們就有了變量sys指向該模塊,利用sys這個變量,就可以訪問sys模塊的所有功能。
sys模塊有一個argv變量,用list存儲了命令行的所有參數。argv至少有一個元素,因為第一個參數永遠是該.py文件的名稱,
例如:
運行python hello.py獲得的sys.argv就是['hello.py'];
運行python hello.py 123abc獲得的sys.argv就是['hello.py', '123abc']。
最后,注意到這兩行代碼:
if __name__=='__main__':test()當我們在命令行運行hello模塊文件時,Python解釋器把一個特殊變量__name__置為__main__。而如果在其他地方導入該hello模塊時,if判斷將失敗。
因此,這種if測試可以讓一個模塊通過命令行運行時執行一些額外的代碼,最常見的就是運行測試。
一個模塊頂層定義的變量,會自動變成模塊的屬性
別名
導入模塊時,還可以使用別名,這樣,可以在運行時根據當前環境選擇最合適的模塊。
比如Python標準庫一般會提供StringIO和cStringIO兩個庫,這兩個庫的接口和功能是一樣的,但是cStringIO是C寫的,速度更快,所以,你會經常看到這樣的寫法:
還有類似simplejson這樣的庫,在Python 2.6之前是獨立的第三方庫,從2.6開始內置,所以,會有這樣的寫法:
作用域
在一個模塊中,會定義很多函數和變量,但有的函數和變量希望給別人使用,有的函數和變量僅僅在模塊內部使用。在Python中,是通過_前綴來實現的。
正常的函數和變量名是公開的(public),可以被直接引用,比如:abc,x123,PI等;
類似__xxx__這樣的變量是特殊變量,可以被直接引用,但是有特殊用途,比如上面的__author__,__name__就是特殊變量,hello模塊定義的文檔注釋也可以用特殊變量__doc__訪問,我們自己的變量一般不要用這種變量名;
類似_xxx和__xxx這樣的函數或變量就是非公開的(private),不應該被直接引用,比如_abc,__abc等;
之所以說,private函數和變量“不應該”被直接引用,而不是“不能”被直接引用,是因為Python并沒有一種方法可以完全限制訪問private函數或變量,但是,從編程習慣上不應該引用private函數或變量。
private函數或變量不應該被別人引用,那它們有什么用呢?請看例子:
它如何工作
首先,我們利用import語句 輸入 sys模塊。基本上,這句語句告訴Python,我們想要使用這個模塊。sys模塊包含了與Python解釋器和它的環境有關的函數。
當Python執行import sys語句的時候,它在sys.path變量中所列目錄中尋找sys.py模塊。如果找到了這個文件,這個模塊的主塊中的語句將被運行,然后這個模塊將能夠被你使用 。注意,初始化過程僅在我們第一次 輸入模塊的時候進行。另外,“sys”是“system”的縮寫。
sys模塊中的argv變量通過使用點號指明——sys.argv——這種方法的一個優勢是這個名稱不會與任何在你的程序中使用的argv變量沖突。另外,它也清晰地表明了這個名稱是sys模塊的一部分。
sys.argv變量是一個字符串的 列表 (列表會在后面的章節詳細解釋)。特別地,sys.argv包含了命令行參數 的列表,即使用命令行傳遞給你的程序的參數。
如果你使用IDE編寫運行這些程序,請在菜單里尋找一個指定程序的命令行參數的方法。
這里,當我們執行python using_sys.py we are arguments的時候,我們使用python命令運行using_sys.py模塊,后面跟著的內容被作為參數傳遞給程序。Python為我們把它存儲在sys.argv變量中。
記住,腳本的名稱總是sys.argv列表的第一個參數。所以,在這里,'using_sys.py'是sys.argv[0]、'we'是sys.argv[1]、'are'是sys.argv[2]以及'arguments'是sys.argv[3]。注意,Python從0開始計數,而非從1開始。
sys.path包含輸入模塊的目錄名列表。我們可以觀察到sys.path的第一個字符串是空的——這個空的字符串表示當前目錄也是sys.path的一部分,這與PYTHONPATH環境變量是相同的。這意味著你可以直接輸入位于當前目錄的模塊。否則,你得把你的模塊放在sys.path所列的目錄之一。
from..import語句
如果你想要直接輸入argv變量到你的程序中(避免在每次使用它時打sys.),那么你可以使用from sys import argv語句。如果你想要輸入所有sys模塊使用的名字,那么可以使用from sys import *語句。這對于所有模塊都適用。一般說來,避免使用from..import而使用import語句,因為這樣可以使你的程序更加易讀,也可以避免名稱的沖突。
下面是一個使用from..import語法的版本。
#!/usr/bin/python # Filename: mymodule_demo2.pyfrom mymodule import sayhi, version # Alternative: # from mymodule import *sayhi() print 'Version', version命名空間和作用域
變量是擁有匹配對象的名字(標識符)。
命名空間是一個包含了變量名稱們(鍵)和它們各自相應的對象們(值)的字典。
一個Python表達式可以訪問局部命名空間和全局命名空間里的變量。同名隱藏的原則同C/C++
每個函數都有自己的命名空間。類的方法的作用域規則和通常函數的一樣。默認任何在函數內賦值的變量都是局部的。因此,如果要給全局變量在一個函數里賦值,必須使用global語句。global VarName的表達式會告訴Python, VarName是一個全局變量,這樣Python就不會在局部命名空間里尋找這個變量了。
例如,我們在全局命名空間里定義一個變量money。我們再在函數內給變量money賦值,然后Python會假定money是一個局部變量。然而,我們并沒有在訪問前聲明一個局部變量money,結果就是會出現一個UnboundLocalError的錯誤。?取消global語句的注釋就能解決這個問題。
globals()和locals()函數
根據調用地方的不同,globals()和locals()函數可被用來返回全局和局部命名空間里的名字。
如果在函數內部調用locals(),返回的是所有能在該函數里訪問的命名。
如果在函數內部調用globals(),返回的是所有在該函數里能訪問的全局名字。
兩個函數的返回類型都是字典。所以名字們能用keys()函數摘取
模塊的__name__
每個模塊都有一個名稱,在模塊中可以通過語句來找出模塊的名稱。這在一個場合特別有用——就如前面所提到的,當一個模塊被第一次輸入的時候,這個模塊的主塊將被運行。假如我們只想在程序本身被使用的時候運行主塊,而在它被別的模塊輸入的時候不運行主塊,我們該怎么做呢?這可以通過模塊的__name__屬性完成。
#!/usr/bin/python # Filename: using_name.pyif __name__ == '__main__':print 'This program is being run by itself' else:print 'I am being imported from another module'輸出 $ python using_name.py This program is being run by itself$ python >>> import using_name I am being imported from another module >>> >>>print __name__ >>>__main__它如何工作
每個Python模塊都有它的__name__,如果它是'__main__',這說明這個模塊被用戶單獨運行,我們可以進行相應的恰當操作。
創建你自己的模塊
#!/usr/bin/python # Filename: mymodule.py def sayhi():print 'Hi, this is mymodule speaking.' version = '0.1' # End of mymodule.py上面是一個 模塊 的例子。你已經看到,它與我們普通的Python程序相比并沒有什么特別之處。我們接下來將看看如何在我們別的Python程序中使用這個模塊。
記住這個模塊應該被放置在我們輸入它的程序的同一個目錄中,或者在sys.path所列目錄之一。
#!/usr/bin/python # Filename: mymodule_demo.py import mymodule mymodule.sayhi() print 'Version', mymodule.version 輸出 $ python mymodule_demo.py Hi, this is mymodule speaking. Version 0.1 在Python中,一個.py文件就稱之為一個模塊(Module)。模塊的名字就是文件的名字。比如有這樣一個文件test.py,在test.py中定義了函數add:
#test.pydef add(a,b):return a+b那么在其他文件中就可以先import test,然后通過test.add(a,b)來調用了,當然也可以通過from test import add來引入。dir()函數
你可以使用內建的dir函數來列出模塊定義的標識符。標識符有函數、類和變量。
當你為dir()提供一個模塊名的時候,它返回模塊定義的名稱列表。如果不提供參數,它返回當前模塊中定義的名稱列表。
$ python >>> import sys >>> dir(sys) # get list of attributes for sys module ['__displayhook__', '__doc__', '__excepthook__', '__name__', '__stderr__', '__stdin__', '__stdout__', '_getframe', 'api_version', 'argv', 'builtin_module_names', 'byteorder', 'call_tracing', 'callstats', 'copyright', 'displayhook', 'exc_clear', 'exc_info', 'exc_type', 'excepthook', 'exec_prefix', 'executable', 'exit', 'getcheckinterval', 'getdefaultencoding', 'getdlopenflags', 'getfilesystemencoding', 'getrecursionlimit', 'getrefcount', 'hexversion', 'maxint', 'maxunicode', 'meta_path','modules', 'path', 'path_hooks', 'path_importer_cache', 'platform', 'prefix', 'ps1', 'ps2', 'setcheckinterval', 'setdlopenflags', 'setprofile', 'setrecursionlimit', 'settrace', 'stderr', 'stdin', 'stdout', 'version', 'version_info', 'warnoptions'] >>> dir() # get list of attributes for current module ['__builtins__', '__doc__', '__name__', 'sys'] >>> >>> a = 5 # create a new variable 'a' >>> dir() ['__builtins__', '__doc__', '__name__', 'a', 'sys'] >>> >>> del a # delete/remove a name >>> >>> dir() ['__builtins__', '__doc__', '__name__', 'sys'] >>>它如何工作
首先,我們來看一下在輸入的sys模塊上使用dir。我們看到它包含一個龐大的屬性列表。
接下來,我們不給dir函數傳遞參數而使用它——默認地,它返回當前模塊的屬性列表。注意,輸入的模塊同樣是列表的一部分。
為了觀察dir的作用,我們定義一個新的變量a并且給它賦一個值,然后檢驗dir,我們觀察到在列表中增加了以上相同的值。我們使用del語句刪除當前模塊中的變量/屬性,這個變化再一次反映在dir的輸出中。
關于del的一點注釋——這個語句在運行后被用來 刪除 一個變量/名稱。在這個例子中,del a,你將無法再使用變量a——它就好像從來沒有存在過一樣。
os和sys模塊
sys模塊
sys模塊主要是用于提供對python解釋器相關的操作
函數
sys.argv #命令行參數List,第一個元素是程序本身路徑 sys.path #返回模塊的搜索路徑,初始化時使用PYTHONPATH環境變量的值 sys.modules.keys() #返回所有已經導入的模塊列表 sys.modules #返回系統導入的模塊字段,key是模塊名,value是模塊 sys.exc_info() #獲取當前正在處理的異常類,exc_type、exc_value、exc_traceback當前處理的異常詳細信息 sys.exit(n) #退出程序,正常退出時exit(0) sys.hexversion #獲取Python解釋程序的版本值,16進制格式如:0x020403F0 sys.version #獲取Python解釋程序的版本信息 sys.platform #返回操作系統平臺名稱 sys.maxint # 最大的Int值 sys.stdout #標準輸出 sys.stdout.write('aaa') #標準輸出內容 sys.stdout.writelines() #無換行輸出 sys.stdin #標準輸入 sys.stdin.read() #輸入一行 sys.stderr #錯誤輸出 sys.exc_clear() #用來清除當前線程所出現的當前的或最近的錯誤信息 sys.exec_prefix #返回平臺獨立的python文件安裝的位置 sys.byteorder #本地字節規則的指示器,big-endian平臺的值是'big',little-endian平臺的值是'little' sys.copyright #記錄python版權相關的東西 sys.api_version #解釋器的C的API版本 sys.version_info #'final'表示最終,也有'candidate'表示候選,表示版本級別,是否有后繼的發行 sys.getdefaultencoding() #返回當前你所用的默認的字符編碼格式 sys.getfilesystemencoding() #返回將Unicode文件名轉換成系統文件名的編碼的名字 sys.builtin_module_names #Python解釋器導入的內建模塊列表 sys.executable #Python解釋程序路徑 sys.getwindowsversion() #獲取Windows的版本 sys.stdin.readline() #從標準輸入讀一行,sys.stdout.write(a) 屏幕輸出a sys.setdefaultencoding(name) #用來設置當前默認的字符編碼(詳細使用參考文檔) sys.displayhook(value) #如果value非空,這個函數會把他輸出到sys.stdout(詳細使用參考文檔) 常用功能sys.arg 獲取位置參數 print(sys.argv)執行該腳本,加參數的打印結果 python3 m_sys.py 1 2 3 4 5['m_sys.py', '1', '2', '3', '4', '5'] 可以發現 sys.arg返回的是整個位置參數,類似于shell的$0 $1... sys.exit(n) 程序退出,n是退出是返回的對象 sys.version 獲取python版本 >>> sys.version '3.5.1 (v3.5.1:37a07cee5969, Dec 5 2015, 21:12:44) \n[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)]' sys.path 返回模塊的搜索路徑列表,可通過添加自定義路徑,來添加自定義模塊 >>> sys.path ['', '/Library/Frameworks/Python.framework/Versions/3.5/lib/python35.zip', '/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5', '/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/plat-darwin', '/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/lib-dynload', '/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages']sys.platform 返回當前系統平臺 linux平臺返回linux,windows平臺返回win32,MAC返回darwin >>> sys.platform 'darwin sys.stdout.write() 輸出內容 >>> sys.stdout.write('asd') asd3 >>> sys.stdout.write('asd') asd3 >>> sys.stdout.write('as') as2
應用:
進度條:
#!/usr/bin/env python # -*- coding: UTF-8 -*-""" sys 和python解析器相關 """from __future__ import division import sys import timedef view_bar(num, total):rate = num / totalrate_num = int(rate * 100)# r = '\r %d%%' %(rate_num)r = '\r%s>%d%%' % ('=' * rate_num, rate_num,) sys.stdout.write(r) sys.stdout.flush if __name__ == '__main__': for i in range(0, 101): time.sleep(0.1)view_bar(i, 100) 效果: ====================================================================================================>100%os模塊
OS模塊是Python標準庫中的一個用于訪問操作系統功能的模塊,使用OS模塊中提供的接口,可以實現跨平臺訪問
用于提供系統級別的操作
os.getcwd() 獲取當前工作目錄,即當前python腳本工作的目錄路徑 os.chdir(dirname) 改變當前腳本工作目錄;相當于shell下cd os.curdir 返回當前目錄: ('.') os.pardir 獲取當前目錄的父目錄字符串名:('..') os.makedirs('dir1/dir2') 可生成多層遞歸目錄 os.removedirs('dirname1') 若目錄為空,則刪除,并遞歸到上一級目錄,如若也為空,則刪除,依此類推 os.mkdir('dirname') 生成單級目錄;相當于shell中mkdir dirname os.rmdir('dirname') 刪除單級空目錄,若目錄不為空則無法刪除,報錯;相當于shell中rmdir dirname os.listdir('dirname') 列出指定目錄下的所有文件和子目錄,包括隱藏文件,并以列表方式打印 os.remove() 刪除一個文件 os.rename(oldname,new) 重命名文件/目錄 os.stat('path/filename') 獲取文件/目錄信息 os.sep 操作系統特定的路徑分隔符,win下為\,Linux下為/ os.linesep 當前平臺使用的行終止符,win下為\t\n,Linux下為\n os.pathsep 用于分割文件路徑的字符串 os.name 字符串指示當前使用平臺。win->'nt'; Linux->'posix' os.system(bash command) 運行shell命令,直接顯示 os.environ 獲取系統環境變量 os.path.abspath(path) 返回path規范化的絕對路徑 os.path.split(path) 將path分割成目錄和文件名二元組返回 os.path.dirname(path) 返回path的目錄。其實就是os.path.split(path)的第一個元素 os.path.basename(path) 返回path最后的文件名。如何path以/或\結尾,那么就會返回空值。即os.path.split(path)的第二個元素 os.path.exists(path) 如果path存在,返回True;如果path不存在,返回False os.path.lexists #路徑存在則返回True,路徑損壞也返回True os.path.isabs(path) 如果path是絕對路徑,返回True os.path.isfile(path) 如果path是一個存在的文件,返回True。否則返回False os.path.isdir(path) 如果path是一個存在的目錄,則返回True。否則返回False os.path.join(path1[, path2[, ...]]) 將多個路徑組合后返回,第一個絕對路徑之前的參數將被忽略 os.path.getatime(path) 返回path所指向的文件或者目錄的最后存取時間 os.path.getmtime(path) 返回path所指向的文件或者目錄的最后修改時間 os.path.commonprefix(list) #返回list(多個路徑)中,所有path共有的最長的路徑。 os.path.expanduser(path) #把path中包含的"~"和"~user"轉換成用戶目錄 os.path.expandvars(path) #根據環境變量的值替換path中包含的”$name”和”${name}” os.access('pathfile',os.W_OK) 檢驗文件權限模式,輸出True,False os.chmod('pathfile',os.W_OK) 改變文件權限模式包
如果不同的人編寫的模塊名相同怎么辦?為了避免模塊名沖突,Python又引入了按目錄來組織模塊的方法,稱為包(Package)。
舉個例子,一個abc.py的文件就是一個名字叫abc的模塊,一個xyz.py的文件就是一個名字叫xyz的模塊。
假設abc和xyz這兩個模塊名字與其他模塊沖突了,可以通過包來組織模塊,避免沖突。方法是選擇一個頂層包名,比如mycompany,按照如下目錄存放:
引入了包以后,只要頂層的包名不與別人沖突,那所有模塊都不會與別人沖突。
現在,abc.py模塊的名字就變成了mycompany.abc,類似的,xyz.py的模塊名變成了mycompany.xyz。
請注意,每一個包目錄下面都會有一個__init__.py的文件,這個文件是必須存在的,否則,Python就把這個目錄當成普通目錄,而不是一個包。
__init__.py可以是空文件,也可以有Python代碼,因為__init__.py本身就是一個模塊,而它的模塊名就是mycompany。
類似的,可以有多級目錄,組成多級層次的包結構。比如如下的目錄結構:
文件www.py的模塊名就是mycompany.web.www,兩個文件utils.py的模塊名分別是mycompany.utils和mycompany.web.utils。
mycompany.web也是一個模塊,請指出該模塊對應的.py文件。
安裝第三方模塊
在Python中,安裝第三方模塊,是通過setuptools這個工具完成的。Python有兩個封裝了setuptools的包管理工具:easy_install和pip。目前官方推薦使用pip。
強烈推薦安裝 pip 安裝 python 第三方模塊
安裝一個第三方庫——Python Imaging Library,這是Python下非常強大的處理圖像的工具庫。
一般來說,第三方庫都會在Python官方的網站pypi.python.org注冊,要安裝一個第三方庫,必須先知道該庫的名稱,可以在官網或者pypi上搜索,比如Python Imaging Library的名稱叫PIL,因此,安裝Python Imaging Library的命令就是:pip install PIL
有了PIL,處理圖片易如反掌。隨便找個圖片生成縮略圖:
默認情況下,Python解釋器會搜索當前目錄、所有已安裝的內置模塊和第三方模塊,搜索路徑存放在sys模塊的path變量中:
>>> import sys >>> sys.path ['', '/Library/Python/2.7/site-packages/pycrypto-2.6.1-py2.7-macosx-10.9-intel.egg', '/Library/Python/2.7/site-packages/PIL-1.1.7-py2.7-macosx-10.9-intel.egg', ...]如果要添加自己的搜索目錄,有兩種方法:
一是直接修改sys.path,添加要搜索的目錄:
第二種方法是設置環境變量PYTHONPATH,該環境變量的內容會被自動添加到模塊搜索路徑中。設置方式與設置Path環境變量類似。注意只需要添加你自己的搜索路徑,Python自己本身的搜索路徑不受影響。
使用__future__
Python每個新版本都會增加一些新功能,或對原來功能作一些改動。有些改動是不兼容舊版本的,即在當前版本運行正常的代碼,到下一個版本運行就可能不正常。
從Python 2.7到Python 3.x就有不兼容的一些改動,比如2.x里的字符串用'xxx'表示str,Unicode字符串用u'xxx'表示unicode,而在3.x中,所有字符串都被視為unicode,因此,寫u'xxx'和'xxx'是完全一致的,而在2.x中以'xxx'表示的str就必須寫成b'xxx',以此表示“二進制字符串”。
要直接把代碼升級到3.x是比較冒進的,因為有大量的改動需要測試。相反,可以在2.7版本中先在一部分代碼中測試一些3.x的特性,如果沒有問題,再移植到3.x不遲。
Python提供了__future__模塊,把下一個新版本的特性導入到當前版本,于是我們就可以在當前版本中測試一些新版本的特性。舉例說明如下:
為了適應Python 3.x的新的字符串的表示方法,在2.7版本的代碼中,可以通過unicode_literals來使用Python 3.x的新的語法:
$ python task.py 'xxx' is unicode? True u'xxx' is unicode? True 'xxx' is str? False b'xxx' is str? True類似的情況還有除法運算。在Python 2.x中,對于除法有兩種情況,如果是整數相除,結果仍是整數,余數會被扔掉,這種除法叫“地板除”:
>>> 10 / 3 3要做精確除法,必須把其中一個數變成浮點數:
>>> 10.0 / 3 3.3333333333333335而在Python 3.x中,所有的除法都是精確除法,地板除用//表示:
$ python3 Python 3.3.2 (default, Jan 22 2014, 09:54:40) [GCC 4.2.1 Compatible Apple LLVM 5.0 (clang-500.2.79)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> 10 / 3 3.3333333333333335 >>> 10 // 3 3如果你想在Python 2.7的代碼中直接使用Python 3.x的除法,可以通過__future__模塊的division實現:
from __future__ import divisionprint '10 / 3 =', 10 / 3 print '10.0 / 3 =', 10.0 / 3 print '10 // 3 =', 10 // 3結果如下: 10 / 3 = 3.33333333333 10.0 / 3 = 3.33333333333 10 // 3 = 3
由于Python是由社區推動的開源并且免費的開發語言,不受商業公司控制,因此,Python的改進往往比較激進,不兼容的情況時有發生。Python為了確保你能順利過渡到新版本,特別提供了__future__模塊,讓你在舊的版本中試驗新版本的一些特性。
總結
以上是生活随笔為你收集整理的简明Python教程学习笔记_3_模块的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 30条架构原则
- 下一篇: 一篇文章带你搞懂 DEX 文件的结构