1、變量賦值及命名規則
① 聲明一個變量及賦值node
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 # _author_soloLi 4 name1="solo" 5 name2=name1 6 print(name1,name2) 7 name1 = "hehe" 8 print(name1,name2)
#name1的值爲hehe,name2的值爲solopython
② 變量命名的規則linux
1 1、變量名只能是 字母、數字或下劃線的任意組合 2 2、變量名的第一個字符不能是數字 3 三、如下關鍵字不能聲明爲變量名['and', 'as', 'assert', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'exec', 'finally', 'for', 'from', 'global','if', 'import', 'in', 'is', 'lambda', 'not', 'or', 'pass', 'print', 'raise', 'return', 'try', 'while', 'with', 'yield']
2、字符編碼
python解釋器在加載 .py 文件中的代碼時,會對內容進行編碼(默認ascill)git
ASCII:最多隻能用 8位來表示(一個字節),即:2**8 = 256,因此,ASCII碼最多隻能表示 256 個符號。顯然ASCII碼沒法將世界上的各類文字和符號所有表示。程序員
Unicode:它爲每種語言中的每一個字符設定了統一而且惟一的二進制編碼,規定雖有的字符和符號最少由 16 位來表示(2個字節),即:2 **16 = 65536,注:此處說的的是最少2個字節,可能更多。正則表達式
UTF-8:是對Unicode編碼的壓縮和優化,他再也不使用最少使用2個字節,而是將全部的字符和符號進行分類:ascii碼中的內容用1個字節保存、歐洲的字符用2個字節保存,東亞的字符用3個字節保存...
注:python2.x版本,默認支持的字符編碼爲ASCll python3.x版本,默認支持的是Unicode,不用聲明字符編碼能夠直接顯示中文。算法
擴展:字符編碼和轉碼,bytes和str區別shell
Python 3最重要的新特性大概要算是對文本和二進制數據做了更爲清晰的區分。文本老是Unicode,由str類型表示,二進制數據則由bytes類型表示。Python 3不會以任意隱式的方式混用str和bytes(相似int和long之間自動轉換),正是這使得二者的區分特別清晰。你不能拼接字符串和字節包,也沒法在字節包裏搜索字符串(反之亦然),也不能將字符串傳入參數爲字節包的函數(反之亦然)。這是件好事。無論怎樣,字符串和字節包之間的界線是必然的,下面的圖解很是重要,務請牢記於心:編程
字符串能夠編碼成字節包,而字節包能夠解碼成字符串:json
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 #-Author-solo 4 msg = "里約奧運" 5 6 print(msg.encode("utf-8")) #若是不指定編碼格式,默認爲utf-8 7 #b'\xe9\x87\x8c\xe7\xba\xa6\xe5\xa5\xa5\xe8\xbf\x90' 8 print(b'\xe9\x87\x8c\xe7\xba\xa6\xe5\xa5\xa5\xe8\xbf\x90'.decode("utf-8")) 9 #里約奧運
爲何要進行編碼和轉碼?
因爲每一個國家電腦的字符編碼格式不統一(列中國:GBK),同一款軟件放到不一樣國家的電腦上會出現亂碼的狀況,出現這種狀況如何解決呢?! 固然因爲全部國家的電腦都支持Unicode萬國碼,那麼咱們能夠把Unicode爲跳板,先把字符編碼轉換爲Unicode,在把Unicode轉換爲另外一個國家的字符編碼(例韓國),則不會出現亂碼的狀況。固然這裏只是轉編碼集並非翻譯成韓文不要弄混了。
① Python3.0進行編碼轉換(默認Unicode編碼)
1 name = "李偉" #此時name爲Unicode編碼 2 name1 = name.encode("utf-8") #Unicode轉爲UTF-8 3 name2 = name1.decode("utf-8") #UTF-8轉爲Unicode 4 5 name3 = name.encode("gbk") #Unicode轉爲GBK 6 name4 = name3.decode("gbk") #GBK轉爲Unicode
② Python2.0中的編碼轉換(默認ascii編碼)
1 ① 聲明字符編碼(utf-8) 2 3 # -*- coding:utf-8 -*- 4 name = "李偉" #ascii碼裏是沒有字符「你好」的,此時的name爲uft-8 5 6 name1 = name.decode("utf-8") #UTF-8轉爲Unicode 7 name2 = name1.encode("gbk") #Unicode轉爲gbk 8 9 ② 使用默認字符編碼(ascii) 10 name = "nihao" #英文字符,且第二行字符聲明去掉,此刻name爲ascii碼 11 12 name1 = name.decode("ascii") #ascii碼轉爲unicode 13 name2 = name1.encode("utf-8") #unicode轉爲utf-8 14 name3 =name1.encode("gbk") #unicode轉爲gbk
3、用戶交互及字符串拼接
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 # _author_soloLi 4 # python2.X與python3.X區別: python2.X raw_input = python3.X input 5 # 提示用戶輸入姓名、年齡、工做、工資並以信息列表的形式打印出 6 7 name = input("Please input your name:") 8 age = int(input("Please input your age:")) #str強制轉換爲int 9 job = input("Please input your job:") 10 salary = input("Please input your salary:") 11 12 info1 = ''' 13 ------------ Info of %s --------- 14 Name:%s 15 Age:%d 16 Job:%s 17 Salary:%s 18 ''' %(name,name,age,job,salary) #%s檢測數據類型爲字符串,%d檢測數據類型爲整數,%f檢測數據類型爲浮點數 強制 19 print(info1) 20 21 # info2 = ''' 22 # ------------ Info of {_Name} --------- 23 # Name:{_Name} 24 # Age:{_Age} 25 # Job:{_Job} 26 # Salary:{_Salary} 27 # ''' .format(_Name=name, 28 # _Age=age, 29 # _Job=job, 30 # _Salary=salary) 31 # print(info2) 32 33 # info3 = ''' 34 # ------------ Info of {0} --------- 35 # Name:{0} 36 # Age:{1} 37 # Job:{2} 38 # Salary:{3} 39 # ''' .format(name,age,job,salary) 40 # print(info3)
對比分析:
一、% :沒法同時傳遞一個變量和元組,又是要加()來保證不拋出typeerror異常
二、+ :每增長一個一個+就會開闢一塊新的內存空間
三、.fomat :不會出現上述問題,有時使用爲了兼容Python2版本。如使用logging庫
4、循環語句(if、while、for、三元運算)
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 # _author_soloLi 4 ################## if語句 ###################### 5 # A = 66 6 # 7 # B = int(input("請輸入0-100的幸運數字:")) 8 # 9 # if B == A: #母級頂格寫 10 # print ("恭喜你猜對了!") #子級強制縮進寫 11 # elif B > A : 12 # print ("猜小了") 13 # else: 14 # print ("猜大了") 15 16 17 ################## while語句 ###################### 18 # A = 66 19 # count = 0 # 設置初始值count=0 20 # 21 # while count < 3 : 22 # 23 # B = int(input("請輸入0-100的數字:")) 24 # 25 # if B == A: 26 # print ("恭喜你猜對了!") 27 # break 28 # elif B > A : 29 # print ("猜大了") 30 # else: 31 # print ("猜小了") 32 # count += 1 33 # else: 34 # print ("你猜的次數太多了!") 35 36 37 ################## for語句 ###################### 38 A = 66 39 i=1 40 for i in range(3):# while判斷count是否小於3,若是小於3則: 41 print("i=",i) 42 B = int(input("請輸入0-100的數字:")) 43 if B == A: 44 print ("恭喜你猜對了!") 45 break 46 elif B > A : 47 print ("猜小了") 48 else: 49 print ("猜大了") 50 i+=1 51 else: 52 print ("你猜的次數太多了!") 53 54 55 ################## 三元運算 ###################### 56 # esult = 值1 if 條件 else 值2 57 # 若是條件成立,那麼將 「值1」 賦值給result變量,不然,將「值2」賦值給result變量
5、基本數據類型
# ①數字 # 1.整型int # 做用:年紀,等級,身份證號,qq號等整型數字相關 # 2.浮點型float # 做用:薪資,身高,體重,體質參數等浮點數相關 # 3.長整形 # python3中沒有長整形的概念 # 進制的轉換:bin(轉成二進制)、oct(轉成八進制)、hex(轉成十六進制) # # ②字符串 # 做用:名字,性別,國籍,地址等描述信息 # 經常使用操做:1.移除空白: strip (參數1:移除什麼符號) # 2.切分: split (參數1:以什麼符號進行切割,參數2:最大切割次數) 切割成列表 # 3.長度: len 統計的字符的長度 # 4.切片: [] (參數1:起始位置:參數2:步長) 顧頭不顧尾 # 5.替換: replace(參數1:old,參數2:new,參數3:替換第幾個) # 6.拼接: format # 7.索引: 只能取 # 8.判斷開頭或結尾: startswith,endswith # 9.其餘。。。 # # ③列表 # 做用:多個裝備,多個愛好,多門課程,多個女友等 # 經常使用操做:1.索引: 便可存也能夠取 # 2.切片: [] 切成新的列表 # 3.追加: append # 4.刪除: remove(按照值)/pop(按照索引) # 5.長度: len 統計的列表的元素個數 # 6.成員運算(包含):in # 7.循環: # 8.插入: insert # 9.其餘。。。 # # ④元組 # 做用:存多個值,對比列表來講,元組不可變,主要是用來讀 # 經常使用操做:除了不能改變元組的以外,其餘操做跟列表相同 # 1.索引: index只能取 # 2.切片: [] # 3.長度: len # 4.循環: # 5.成員運算(包含):in # 6.統計: count # # ⑤字典 # 做用:存多個值,key-value(鍵值對)存取,取值速度快 # 經常使用操做:1.按key存取值:可存可取 # 2.循環: 無序 # 3.長度: len # 4.刪除: pop 第2個參數設置none 程序即便取不到值也不報錯 # 5.成員運算(包含):in # 6.取值: get(不存在程序不報錯)/info(不存在程序報錯) # 7.其餘。。。 # # ⑥集合 # 做用:去重,關係運算, # 經常使用操做:1.長度: len # 2.添加: add(只能添加一個元素)/update(能夠添加多個元素) # 3.刪除: remove(刪除指定元素)/pop(隨機刪除元素)/discard(刪除指定元素,與remove區別在於,若是元素不存在也不會報錯) # 4.交集: & # 5.差集: - # 6.對稱差集: ^ # 7.成員運算: in # 8.合集: | # 9.父集: >,>= # 10.子集: <,<= # # 小結: # 按存值個數區分 # 標量/原子類型:數字,字符串 # 容器類型:列表,元組,字典 # # 按可變不可變區分 # 可變:列表,字典 # 不可變:數字,字符串,元組 # # 按訪問方式區分 # 直接訪問:數字 # 按照索引訪問(序列類型):字符串,列表,元組 # key訪問(映射類型) 字典
1、整型
如: 1八、7三、84
類型經常使用功能:
1 abs(x) #返回絕對值 2 x+y,x-y,x*y,x/y #加減乘除 3 x/y #取商,浮點數相除保留餘數 4 x//y #取商,浮點數相除餘數爲0 5 x%y #取餘 6 x**y #冪次方 7 cmp(x,y) #兩個數比較,返回True或False相等則爲0 8 coerce(x,y) #強制把兩個數生成一個元組 9 divmod(x,y) #相除獲得商和餘數組成的元組 10 float(x) #轉換爲浮點型 11 str(x) #轉換爲字符串 12 hex(x) #轉換爲16進制 13 oct(x) #轉換8進制
更多功能:
1 class int(object): 2 """ 3 int(x=0) -> int or long 4 int(x, base=10) -> int or long 5 6 Convert a number or string to an integer, or return 0 if no arguments 7 are given. If x is floating point, the conversion truncates towards zero. 8 If x is outside the integer range, the function returns a long instead. 9 10 If x is not a number or if base is given, then x must be a string or 11 Unicode object representing an integer literal in the given base. The 12 literal can be preceded by '+' or '-' and be surrounded by whitespace. 13 The base defaults to 10. Valid bases are 0 and 2-36. Base 0 means to 14 interpret the base from the string as an integer literal. 15 >>> int('0b100', base=0) 16 """ 17 def bit_length(self): 18 """ 返回表示該數字的時佔用的最少位數 """ 19 """ 20 int.bit_length() -> int 21 22 Number of bits necessary to represent self in binary. 23 >>> bin(37) 24 '0b100101' 25 >>> (37).bit_length() 26 """ 27 return 0 28 29 def conjugate(self, *args, **kwargs): # real signature unknown 30 """ 返回該複數的共軛複數 """ 31 """ Returns self, the complex conjugate of any int. """ 32 pass 33 34 def __abs__(self): 35 """ 返回絕對值 """ 36 """ x.__abs__() <==> abs(x) """ 37 pass 38 39 def __add__(self, y): 40 """ x.__add__(y) <==> x+y """ 41 pass 42 43 def __and__(self, y): 44 """ x.__and__(y) <==> x&y """ 45 pass 46 47 def __cmp__(self, y): 48 """ 比較兩個數大小 """ 49 """ x.__cmp__(y) <==> cmp(x,y) """ 50 pass 51 52 def __coerce__(self, y): 53 """ 強制生成一個元組 """ 54 """ x.__coerce__(y) <==> coerce(x, y) """ 55 pass 56 57 def __divmod__(self, y): 58 """ 相除,獲得商和餘數組成的元組 """ 59 """ x.__divmod__(y) <==> divmod(x, y) """ 60 pass 61 62 def __div__(self, y): 63 """ x.__div__(y) <==> x/y """ 64 pass 65 66 def __float__(self): 67 """ 轉換爲浮點類型 """ 68 """ x.__float__() <==> float(x) """ 69 pass 70 71 def __floordiv__(self, y): 72 """ x.__floordiv__(y) <==> x//y """ 73 pass 74 75 def __format__(self, *args, **kwargs): # real signature unknown 76 pass 77 78 def __getattribute__(self, name): 79 """ x.__getattribute__('name') <==> x.name """ 80 pass 81 82 def __getnewargs__(self, *args, **kwargs): # real signature unknown 83 """ 內部調用 __new__方法或建立對象時傳入參數使用 """ 84 pass 85 86 def __hash__(self): 87 """若是對象object爲哈希表類型,返回對象object的哈希值。哈希值爲整數。在字典查找中,哈希值用於快速比較字典的鍵。兩個數值若是相等,則哈希值也相等。""" 88 """ x.__hash__() <==> hash(x) """ 89 pass 90 91 def __hex__(self): 92 """ 返回當前數的 十六進制 表示 """ 93 """ x.__hex__() <==> hex(x) """ 94 pass 95 96 def __index__(self): 97 """ 用於切片,數字無心義 """ 98 """ x[y:z] <==> x[y.__index__():z.__index__()] """ 99 pass 100 101 def __init__(self, x, base=10): # known special case of int.__init__ 102 """ 構造方法,執行 x = 123 或 x = int(10) 時,自動調用,暫時忽略 """ 103 """ 104 int(x=0) -> int or long 105 int(x, base=10) -> int or long 106 107 Convert a number or string to an integer, or return 0 if no arguments 108 are given. If x is floating point, the conversion truncates towards zero. 109 If x is outside the integer range, the function returns a long instead. 110 111 If x is not a number or if base is given, then x must be a string or 112 Unicode object representing an integer literal in the given base. The 113 literal can be preceded by '+' or '-' and be surrounded by whitespace. 114 The base defaults to 10. Valid bases are 0 and 2-36. Base 0 means to 115 interpret the base from the string as an integer literal. 116 >>> int('0b100', base=0) 117 # (copied from class doc) 118 """ 119 pass 120 121 def __int__(self): 122 """ 轉換爲整數 """ 123 """ x.__int__() <==> int(x) """ 124 pass 125 126 def __invert__(self): 127 """ x.__invert__() <==> ~x """ 128 pass 129 130 def __long__(self): 131 """ 轉換爲長整數 """ 132 """ x.__long__() <==> long(x) """ 133 pass 134 135 def __lshift__(self, y): 136 """ x.__lshift__(y) <==> x<<y """ 137 pass 138 139 def __mod__(self, y): 140 """ x.__mod__(y) <==> x%y """ 141 pass 142 143 def __mul__(self, y): 144 """ x.__mul__(y) <==> x*y """ 145 pass 146 147 def __neg__(self): 148 """ x.__neg__() <==> -x """ 149 pass 150 151 @staticmethod # known case of __new__ 152 def __new__(S, *more): 153 """ T.__new__(S, ...) -> a new object with type S, a subtype of T """ 154 pass 155 156 def __nonzero__(self): 157 """ x.__nonzero__() <==> x != 0 """ 158 pass 159 160 def __oct__(self): 161 """ 返回改值的 八進制 表示 """ 162 """ x.__oct__() <==> oct(x) """ 163 pass 164 165 def __or__(self, y): 166 """ x.__or__(y) <==> x|y """ 167 pass 168 169 def __pos__(self): 170 """ x.__pos__() <==> +x """ 171 pass 172 173 def __pow__(self, y, z=None): 174 """ 冪,次方 """ 175 """ x.__pow__(y[, z]) <==> pow(x, y[, z]) """ 176 pass 177 178 def __radd__(self, y): 179 """ x.__radd__(y) <==> y+x """ 180 pass 181 182 def __rand__(self, y): 183 """ x.__rand__(y) <==> y&x """ 184 pass 185 186 def __rdivmod__(self, y): 187 """ x.__rdivmod__(y) <==> divmod(y, x) """ 188 pass 189 190 def __rdiv__(self, y): 191 """ x.__rdiv__(y) <==> y/x """ 192 pass 193 194 def __repr__(self): 195 """轉化爲解釋器可讀取的形式 """ 196 """ x.__repr__() <==> repr(x) """ 197 pass 198 199 def __str__(self): 200 """轉換爲人閱讀的形式,若是沒有適於人閱讀的解釋形式的話,則返回解釋器課閱讀的形式""" 201 """ x.__str__() <==> str(x) """ 202 pass 203 204 def __rfloordiv__(self, y): 205 """ x.__rfloordiv__(y) <==> y//x """ 206 pass 207 208 def __rlshift__(self, y): 209 """ x.__rlshift__(y) <==> y<<x """ 210 pass 211 212 def __rmod__(self, y): 213 """ x.__rmod__(y) <==> y%x """ 214 pass 215 216 def __rmul__(self, y): 217 """ x.__rmul__(y) <==> y*x """ 218 pass 219 220 def __ror__(self, y): 221 """ x.__ror__(y) <==> y|x """ 222 pass 223 224 def __rpow__(self, x, z=None): 225 """ y.__rpow__(x[, z]) <==> pow(x, y[, z]) """ 226 pass 227 228 def __rrshift__(self, y): 229 """ x.__rrshift__(y) <==> y>>x """ 230 pass 231 232 def __rshift__(self, y): 233 """ x.__rshift__(y) <==> x>>y """ 234 pass 235 236 def __rsub__(self, y): 237 """ x.__rsub__(y) <==> y-x """ 238 pass 239 240 def __rtruediv__(self, y): 241 """ x.__rtruediv__(y) <==> y/x """ 242 pass 243 244 def __rxor__(self, y): 245 """ x.__rxor__(y) <==> y^x """ 246 pass 247 248 def __sub__(self, y): 249 """ x.__sub__(y) <==> x-y """ 250 pass 251 252 def __truediv__(self, y): 253 """ x.__truediv__(y) <==> x/y """ 254 pass 255 256 def __trunc__(self, *args, **kwargs): 257 """ 返回數值被截取爲整形的值,在整形中無心義 """ 258 pass 259 260 def __xor__(self, y): 261 """ x.__xor__(y) <==> x^y """ 262 pass 263 264 denominator = property(lambda self: object(), lambda self, v: None, lambda self: None) # default 265 """ 分母 = 1 """ 266 """the denominator of a rational number in lowest terms""" 267 268 imag = property(lambda self: object(), lambda self, v: None, lambda self: None) # default 269 """ 虛數,無心義 """ 270 """the imaginary part of a complex number""" 271 272 numerator = property(lambda self: object(), lambda self, v: None, lambda self: None) # default 273 """ 分子 = 數字大小 """ 274 """the numerator of a rational number in lowest terms""" 275 276 real = property(lambda self: object(), lambda self, v: None, lambda self: None) # default 277 """ 實屬,無心義 """ 278 """the real part of a complex number""" 279 280 int 281 282 int
2、長整型
如:214748364九、9223372036854775807
類型經常使用功能:
1 #長整型功能與整形基本相似
更多功能:
1 class long(object): 2 """ 3 long(x=0) -> long 4 long(x, base=10) -> long 5 6 Convert a number or string to a long integer, or return 0L if no arguments 7 are given. If x is floating point, the conversion truncates towards zero. 8 9 If x is not a number or if base is given, then x must be a string or 10 Unicode object representing an integer literal in the given base. The 11 literal can be preceded by '+' or '-' and be surrounded by whitespace. 12 The base defaults to 10. Valid bases are 0 and 2-36. Base 0 means to 13 interpret the base from the string as an integer literal. 14 >>> int('0b100', base=0) 15 4L 16 """ 17 def bit_length(self): # real signature unknown; restored from __doc__ 18 """ 19 long.bit_length() -> int or long 20 21 Number of bits necessary to represent self in binary. 22 >>> bin(37L) 23 '0b100101' 24 >>> (37L).bit_length() 25 """ 26 return 0 27 28 def conjugate(self, *args, **kwargs): # real signature unknown 29 """ Returns self, the complex conjugate of any long. """ 30 pass 31 32 def __abs__(self): # real signature unknown; restored from __doc__ 33 """ x.__abs__() <==> abs(x) """ 34 pass 35 36 def __add__(self, y): # real signature unknown; restored from __doc__ 37 """ x.__add__(y) <==> x+y """ 38 pass 39 40 def __and__(self, y): # real signature unknown; restored from __doc__ 41 """ x.__and__(y) <==> x&y """ 42 pass 43 44 def __cmp__(self, y): # real signature unknown; restored from __doc__ 45 """ x.__cmp__(y) <==> cmp(x,y) """ 46 pass 47 48 def __coerce__(self, y): # real signature unknown; restored from __doc__ 49 """ x.__coerce__(y) <==> coerce(x, y) """ 50 pass 51 52 def __divmod__(self, y): # real signature unknown; restored from __doc__ 53 """ x.__divmod__(y) <==> divmod(x, y) """ 54 pass 55 56 def __div__(self, y): # real signature unknown; restored from __doc__ 57 """ x.__div__(y) <==> x/y """ 58 pass 59 60 def __float__(self): # real signature unknown; restored from __doc__ 61 """ x.__float__() <==> float(x) """ 62 pass 63 64 def __floordiv__(self, y): # real signature unknown; restored from __doc__ 65 """ x.__floordiv__(y) <==> x//y """ 66 pass 67 68 def __format__(self, *args, **kwargs): # real signature unknown 69 pass 70 71 def __getattribute__(self, name): # real signature unknown; restored from __doc__ 72 """ x.__getattribute__('name') <==> x.name """ 73 pass 74 75 def __getnewargs__(self, *args, **kwargs): # real signature unknown 76 pass 77 78 def __hash__(self): # real signature unknown; restored from __doc__ 79 """ x.__hash__() <==> hash(x) """ 80 pass 81 82 def __hex__(self): # real signature unknown; restored from __doc__ 83 """ x.__hex__() <==> hex(x) """ 84 pass 85 86 def __index__(self): # real signature unknown; restored from __doc__ 87 """ x[y:z] <==> x[y.__index__():z.__index__()] """ 88 pass 89 90 def __init__(self, x=0): # real signature unknown; restored from __doc__ 91 pass 92 93 def __int__(self): # real signature unknown; restored from __doc__ 94 """ x.__int__() <==> int(x) """ 95 pass 96 97 def __invert__(self): # real signature unknown; restored from __doc__ 98 """ x.__invert__() <==> ~x """ 99 pass 100 101 def __long__(self): # real signature unknown; restored from __doc__ 102 """ x.__long__() <==> long(x) """ 103 pass 104 105 def __lshift__(self, y): # real signature unknown; restored from __doc__ 106 """ x.__lshift__(y) <==> x<<y """ 107 pass 108 109 def __mod__(self, y): # real signature unknown; restored from __doc__ 110 """ x.__mod__(y) <==> x%y """ 111 pass 112 113 def __mul__(self, y): # real signature unknown; restored from __doc__ 114 """ x.__mul__(y) <==> x*y """ 115 pass 116 117 def __neg__(self): # real signature unknown; restored from __doc__ 118 """ x.__neg__() <==> -x """ 119 pass 120 121 @staticmethod # known case of __new__ 122 def __new__(S, *more): # real signature unknown; restored from __doc__ 123 """ T.__new__(S, ...) -> a new object with type S, a subtype of T """ 124 pass 125 126 def __nonzero__(self): # real signature unknown; restored from __doc__ 127 """ x.__nonzero__() <==> x != 0 """ 128 pass 129 130 def __oct__(self): # real signature unknown; restored from __doc__ 131 """ x.__oct__() <==> oct(x) """ 132 pass 133 134 def __or__(self, y): # real signature unknown; restored from __doc__ 135 """ x.__or__(y) <==> x|y """ 136 pass 137 138 def __pos__(self): # real signature unknown; restored from __doc__ 139 """ x.__pos__() <==> +x """ 140 pass 141 142 def __pow__(self, y, z=None): # real signature unknown; restored from __doc__ 143 """ x.__pow__(y[, z]) <==> pow(x, y[, z]) """ 144 pass 145 146 def __radd__(self, y): # real signature unknown; restored from __doc__ 147 """ x.__radd__(y) <==> y+x """ 148 pass 149 150 def __rand__(self, y): # real signature unknown; restored from __doc__ 151 """ x.__rand__(y) <==> y&x """ 152 pass 153 154 def __rdivmod__(self, y): # real signature unknown; restored from __doc__ 155 """ x.__rdivmod__(y) <==> divmod(y, x) """ 156 pass 157 158 def __rdiv__(self, y): # real signature unknown; restored from __doc__ 159 """ x.__rdiv__(y) <==> y/x """ 160 pass 161 162 def __repr__(self): # real signature unknown; restored from __doc__ 163 """ x.__repr__() <==> repr(x) """ 164 pass 165 166 def __rfloordiv__(self, y): # real signature unknown; restored from __doc__ 167 """ x.__rfloordiv__(y) <==> y//x """ 168 pass 169 170 def __rlshift__(self, y): # real signature unknown; restored from __doc__ 171 """ x.__rlshift__(y) <==> y<<x """ 172 pass 173 174 def __rmod__(self, y): # real signature unknown; restored from __doc__ 175 """ x.__rmod__(y) <==> y%x """ 176 pass 177 178 def __rmul__(self, y): # real signature unknown; restored from __doc__ 179 """ x.__rmul__(y) <==> y*x """ 180 pass 181 182 def __ror__(self, y): # real signature unknown; restored from __doc__ 183 """ x.__ror__(y) <==> y|x """ 184 pass 185 186 def __rpow__(self, x, z=None): # real signature unknown; restored from __doc__ 187 """ y.__rpow__(x[, z]) <==> pow(x, y[, z]) """ 188 pass 189 190 def __rrshift__(self, y): # real signature unknown; restored from __doc__ 191 """ x.__rrshift__(y) <==> y>>x """ 192 pass 193 194 def __rshift__(self, y): # real signature unknown; restored from __doc__ 195 """ x.__rshift__(y) <==> x>>y """ 196 pass 197 198 def __rsub__(self, y): # real signature unknown; restored from __doc__ 199 """ x.__rsub__(y) <==> y-x """ 200 pass 201 202 def __rtruediv__(self, y): # real signature unknown; restored from __doc__ 203 """ x.__rtruediv__(y) <==> y/x """ 204 pass 205 206 def __rxor__(self, y): # real signature unknown; restored from __doc__ 207 """ x.__rxor__(y) <==> y^x """ 208 pass 209 210 def __sizeof__(self, *args, **kwargs): # real signature unknown 211 """ Returns size in memory, in bytes """ 212 pass 213 214 def __str__(self): # real signature unknown; restored from __doc__ 215 """ x.__str__() <==> str(x) """ 216 pass 217 218 def __sub__(self, y): # real signature unknown; restored from __doc__ 219 """ x.__sub__(y) <==> x-y """ 220 pass 221 222 def __truediv__(self, y): # real signature unknown; restored from __doc__ 223 """ x.__truediv__(y) <==> x/y """ 224 pass 225 226 def __trunc__(self, *args, **kwargs): # real signature unknown 227 """ Truncating an Integral returns itself. """ 228 pass 229 230 def __xor__(self, y): # real signature unknown; restored from __doc__ 231 """ x.__xor__(y) <==> x^y """ 232 pass 233 234 denominator = property(lambda self: object(), lambda self, v: None, lambda self: None) # default 235 """the denominator of a rational number in lowest terms""" 236 237 imag = property(lambda self: object(), lambda self, v: None, lambda self: None) # default 238 """the imaginary part of a complex number""" 239 240 numerator = property(lambda self: object(), lambda self, v: None, lambda self: None) # default 241 """the numerator of a rational number in lowest terms""" 242 243 real = property(lambda self: object(), lambda self, v: None, lambda self: None) # default 244 """the real part of a complex number""" 245 246 long 247 248 long
注:跟C語言不一樣,Python的長整數沒有指定位寬,即:Python沒有限制長整數數值的大小,但實際上因爲機器內存有限,咱們使用的長整數數值不可能無限大。自從Python2.2起,若是整數發生溢出,Python會自動將整數數據轉換爲長整數,因此現在在長整數數據後面不加字母L也不會致使嚴重後果
3、浮點型
如:3.1四、2.88
類型經常使用功能:
1 #浮點型功能與整形基本相似
更多功能:
1 class float(object): 2 """ 3 float(x) -> floating point number 4 5 Convert a string or number to a floating point number, if possible. 6 """ 7 def as_integer_ratio(self): 8 """ 獲取改值的最簡比 """ 9 """ 10 float.as_integer_ratio() -> (int, int) 11 12 Return a pair of integers, whose ratio is exactly equal to the original 13 float and with a positive denominator. 14 Raise OverflowError on infinities and a ValueError on NaNs. 15 16 >>> (10.0).as_integer_ratio() 17 (10, 1) 18 >>> (0.0).as_integer_ratio() 19 (0, 1) 20 >>> (-.25).as_integer_ratio() 21 (-1, 4) 22 """ 23 pass 24 25 def conjugate(self, *args, **kwargs): # real signature unknown 26 """ Return self, the complex conjugate of any float. """ 27 pass 28 29 def fromhex(self, string): 30 """ 將十六進制字符串轉換成浮點型 """ 31 """ 32 float.fromhex(string) -> float 33 34 Create a floating-point number from a hexadecimal string. 35 >>> float.fromhex('0x1.ffffp10') 36 2047.984375 37 >>> float.fromhex('-0x1p-1074') 38 -4.9406564584124654e-324 39 """ 40 return 0.0 41 42 def hex(self): 43 """ 返回當前值的 16 進製表示 """ 44 """ 45 float.hex() -> string 46 47 Return a hexadecimal representation of a floating-point number. 48 >>> (-0.1).hex() 49 '-0x1.999999999999ap-4' 50 >>> 3.14159.hex() 51 '0x1.921f9f01b866ep+1' 52 """ 53 return "" 54 55 def is_integer(self, *args, **kwargs): # real signature unknown 56 """ Return True if the float is an integer. """ 57 pass 58 59 def __abs__(self): 60 """ x.__abs__() <==> abs(x) """ 61 pass 62 63 def __add__(self, y): 64 """ x.__add__(y) <==> x+y """ 65 pass 66 67 def __coerce__(self, y): 68 """ x.__coerce__(y) <==> coerce(x, y) """ 69 pass 70 71 def __divmod__(self, y): 72 """ x.__divmod__(y) <==> divmod(x, y) """ 73 pass 74 75 def __div__(self, y): 76 """ x.__div__(y) <==> x/y """ 77 pass 78 79 def __eq__(self, y): 80 """ x.__eq__(y) <==> x==y """ 81 pass 82 83 def __float__(self): 84 """ x.__float__() <==> float(x) """ 85 pass 86 87 def __floordiv__(self, y): 88 """ x.__floordiv__(y) <==> x//y """ 89 pass 90 91 def __format__(self, format_spec): 92 """ 93 float.__format__(format_spec) -> string 94 95 Formats the float according to format_spec. 96 """ 97 return "" 98 99 def __getattribute__(self, name): 100 """ x.__getattribute__('name') <==> x.name """ 101 pass 102 103 def __getformat__(self, typestr): 104 """ 105 float.__getformat__(typestr) -> string 106 107 You probably don't want to use this function. It exists mainly to be 108 used in Python's test suite. 109 110 typestr must be 'double' or 'float'. This function returns whichever of 111 'unknown', 'IEEE, big-endian' or 'IEEE, little-endian' best describes the 112 format of floating point numbers used by the C type named by typestr. 113 """ 114 return "" 115 116 def __getnewargs__(self, *args, **kwargs): # real signature unknown 117 pass 118 119 def __ge__(self, y): 120 """ x.__ge__(y) <==> x>=y """ 121 pass 122 123 def __gt__(self, y): 124 """ x.__gt__(y) <==> x>y """ 125 pass 126 127 def __hash__(self): 128 """ x.__hash__() <==> hash(x) """ 129 pass 130 131 def __init__(self, x): 132 pass 133 134 def __int__(self): 135 """ x.__int__() <==> int(x) """ 136 pass 137 138 def __le__(self, y): 139 """ x.__le__(y) <==> x<=y """ 140 pass 141 142 def __long__(self): 143 """ x.__long__() <==> long(x) """ 144 pass 145 146 def __lt__(self, y): 147 """ x.__lt__(y) <==> x<y """ 148 pass 149 150 def __mod__(self, y): 151 """ x.__mod__(y) <==> x%y """ 152 pass 153 154 def __mul__(self, y): 155 """ x.__mul__(y) <==> x*y """ 156 pass 157 158 def __neg__(self): 159 """ x.__neg__() <==> -x """ 160 pass 161 162 @staticmethod # known case of __new__ 163 def __new__(S, *more): 164 """ T.__new__(S, ...) -> a new object with type S, a subtype of T """ 165 pass 166 167 def __ne__(self, y): 168 """ x.__ne__(y) <==> x!=y """ 169 pass 170 171 def __nonzero__(self): 172 """ x.__nonzero__() <==> x != 0 """ 173 pass 174 175 def __pos__(self): 176 """ x.__pos__() <==> +x """ 177 pass 178 179 def __pow__(self, y, z=None): 180 """ x.__pow__(y[, z]) <==> pow(x, y[, z]) """ 181 pass 182 183 def __radd__(self, y): 184 """ x.__radd__(y) <==> y+x """ 185 pass 186 187 def __rdivmod__(self, y): 188 """ x.__rdivmod__(y) <==> divmod(y, x) """ 189 pass 190 191 def __rdiv__(self, y): 192 """ x.__rdiv__(y) <==> y/x """ 193 pass 194 195 def __repr__(self): 196 """ x.__repr__() <==> repr(x) """ 197 pass 198 199 def __rfloordiv__(self, y): 200 """ x.__rfloordiv__(y) <==> y//x """ 201 pass 202 203 def __rmod__(self, y): 204 """ x.__rmod__(y) <==> y%x """ 205 pass 206 207 def __rmul__(self, y): 208 """ x.__rmul__(y) <==> y*x """ 209 pass 210 211 def __rpow__(self, x, z=None): 212 """ y.__rpow__(x[, z]) <==> pow(x, y[, z]) """ 213 pass 214 215 def __rsub__(self, y): 216 """ x.__rsub__(y) <==> y-x """ 217 pass 218 219 def __rtruediv__(self, y): 220 """ x.__rtruediv__(y) <==> y/x """ 221 pass 222 223 def __setformat__(self, typestr, fmt): 224 """ 225 float.__setformat__(typestr, fmt) -> None 226 227 You probably don't want to use this function. It exists mainly to be 228 used in Python's test suite. 229 230 typestr must be 'double' or 'float'. fmt must be one of 'unknown', 231 'IEEE, big-endian' or 'IEEE, little-endian', and in addition can only be 232 one of the latter two if it appears to match the underlying C reality. 233 234 Override the automatic determination of C-level floating point type. 235 This affects how floats are converted to and from binary strings. 236 """ 237 pass 238 239 def __str__(self): 240 """ x.__str__() <==> str(x) """ 241 pass 242 243 def __sub__(self, y): 244 """ x.__sub__(y) <==> x-y """ 245 pass 246 247 def __truediv__(self, y): 248 """ x.__truediv__(y) <==> x/y """ 249 pass 250 251 def __trunc__(self, *args, **kwargs): # real signature unknown 252 """ Return the Integral closest to x between 0 and x. """ 253 pass 254 255 imag = property(lambda self: object(), lambda self, v: None, lambda self: None) # default 256 """the imaginary part of a complex number""" 257 258 real = property(lambda self: object(), lambda self, v: None, lambda self: None) # default 259 """the real part of a complex number""" 260 261 float 262 263 float
4、字符串
如:'wupeiqi'、'alex'、'solo'
類型經常使用功能:
1 name = "my name is solo" 2 print(name.capitalize()) #首字母大寫 3 #My name is solo 4 print(name.count("l")) #統計字符串出現某個字符的個數 5 #2 6 print(name.center(30,"-")) #打印30個字符,不夠的-補齊 7 #--------my name is solo-------- 8 print(name.ljust(30,"-")) #打印30個字符,不夠的-補齊,字符串在左邊 9 #my name is solo---------------- 10 print(name.endswith("solo")) #判斷字符串是否以solo結尾 11 #True 12 print(name[name.find("na"):]) #find尋找na所在的索引下標 字符串也能夠切片 13 #name is solo 14 print("5.3".isdigit()) #判斷字符是否爲整數 15 #False 16 print("a_1A".isidentifier()) #判斷是否是一個合法的標識符(變量名) 17 #True 18 print("+".join(["1","2","3"])) #把join後的內容加入到前面字符串中,以+爲分割符 19 #1+2+3 20 print("\nsolo".strip()) #去換行符 21 #solo 22 print("1+2+3+4".split("+")) #以+爲分隔符生成新的列表,默認不寫爲空格 23 #['1', '2', '3', '4'] 24 name = "my name is {name} and i an {year} old" 25 print(name.format(name="solo",year=20) 26 #my name is solo and i an 20 old 27 print(name.format_map({"name":"solo","year":20})) #不多用 28 #my name is solo and i an 20 old 29 p = str.maketrans("abcdefli","12345678") #轉換 一一對應 30 print("lianzhilei".translate(p)) 31 #781nzh8758
更多功能:
1 class str(basestring): 2 """ 3 str(object='') -> string 4 5 Return a nice string representation of the object. 6 If the argument is a string, the return value is the same object. 7 """ 8 def capitalize(self): 9 """ 首字母變大寫 """ 10 """ 11 S.capitalize() -> string 12 13 Return a copy of the string S with only its first character 14 capitalized. 15 """ 16 return "" 17 18 def center(self, width, fillchar=None): 19 """ 內容居中,width:總長度;fillchar:空白處填充內容,默認無 """ 20 """ 21 S.center(width[, fillchar]) -> string 22 23 Return S centered in a string of length width. Padding is 24 done using the specified fill character (default is a space) 25 """ 26 return "" 27 28 def count(self, sub, start=None, end=None): 29 """ 子序列個數 """ 30 """ 31 S.count(sub[, start[, end]]) -> int 32 33 Return the number of non-overlapping occurrences of substring sub in 34 string S[start:end]. Optional arguments start and end are interpreted 35 as in slice notation. 36 """ 37 return 0 38 39 def decode(self, encoding=None, errors=None): 40 """ 解碼 """ 41 """ 42 S.decode([encoding[,errors]]) -> object 43 44 Decodes S using the codec registered for encoding. encoding defaults 45 to the default encoding. errors may be given to set a different error 46 handling scheme. Default is 'strict' meaning that encoding errors raise 47 a UnicodeDecodeError. Other possible values are 'ignore' and 'replace' 48 as well as any other name registered with codecs.register_error that is 49 able to handle UnicodeDecodeErrors. 50 """ 51 return object() 52 53 def encode(self, encoding=None, errors=None): 54 """ 編碼,針對unicode """ 55 """ 56 S.encode([encoding[,errors]]) -> object 57 58 Encodes S using the codec registered for encoding. encoding defaults 59 to the default encoding. errors may be given to set a different error 60 handling scheme. Default is 'strict' meaning that encoding errors raise 61 a UnicodeEncodeError. Other possible values are 'ignore', 'replace' and 62 'xmlcharrefreplace' as well as any other name registered with 63 codecs.register_error that is able to handle UnicodeEncodeErrors. 64 """ 65 return object() 66 67 def endswith(self, suffix, start=None, end=None): 68 """ 是否以 xxx 結束 """ 69 """ 70 S.endswith(suffix[, start[, end]]) -> bool 71 72 Return True if S ends with the specified suffix, False otherwise. 73 With optional start, test S beginning at that position. 74 With optional end, stop comparing S at that position. 75 suffix can also be a tuple of strings to try. 76 """ 77 return False 78 79 def expandtabs(self, tabsize=None): 80 """ 將tab轉換成空格,默認一個tab轉換成8個空格 """ 81 """ 82 S.expandtabs([tabsize]) -> string 83 84 Return a copy of S where all tab characters are expanded using spaces. 85 If tabsize is not given, a tab size of 8 characters is assumed. 86 """ 87 return "" 88 89 def find(self, sub, start=None, end=None): 90 """ 尋找子序列位置,若是沒找到,返回 -1 """ 91 """ 92 S.find(sub [,start [,end]]) -> int 93 94 Return the lowest index in S where substring sub is found, 95 such that sub is contained within S[start:end]. Optional 96 arguments start and end are interpreted as in slice notation. 97 98 Return -1 on failure. 99 """ 100 return 0 101 102 def format(*args, **kwargs): # known special case of str.format 103 """ 字符串格式化,動態參數,將函數式編程時細說 """ 104 """ 105 S.format(*args, **kwargs) -> string 106 107 Return a formatted version of S, using substitutions from args and kwargs. 108 The substitutions are identified by braces ('{' and '}'). 109 """ 110 pass 111 112 def index(self, sub, start=None, end=None): 113 """ 子序列位置,若是沒找到,報錯 """ 114 S.index(sub [,start [,end]]) -> int 115 116 Like S.find() but raise ValueError when the substring is not found. 117 """ 118 return 0 119 120 def isalnum(self): 121 """ 是不是字母和數字 """ 122 """ 123 S.isalnum() -> bool 124 125 Return True if all characters in S are alphanumeric 126 and there is at least one character in S, False otherwise. 127 """ 128 return False 129 130 def isalpha(self): 131 """ 是不是字母 """ 132 """ 133 S.isalpha() -> bool 134 135 Return True if all characters in S are alphabetic 136 and there is at least one character in S, False otherwise. 137 """ 138 return False 139 140 def isdigit(self): 141 """ 是不是數字 """ 142 """ 143 S.isdigit() -> bool 144 145 Return True if all characters in S are digits 146 and there is at least one character in S, False otherwise. 147 """ 148 return False 149 150 def islower(self): 151 """ 是否小寫 """ 152 """ 153 S.islower() -> bool 154 155 Return True if all cased characters in S are lowercase and there is 156 at least one cased character in S, False otherwise. 157 """ 158 return False 159 160 def isspace(self): 161 """ 162 S.isspace() -> bool 163 164 Return True if all characters in S are whitespace 165 and there is at least one character in S, False otherwise. 166 """ 167 return False 168 169 def istitle(self): 170 """ 171 S.istitle() -> bool 172 173 Return True if S is a titlecased string and there is at least one 174 character in S, i.e. uppercase characters may only follow uncased 175 characters and lowercase characters only cased ones. Return False 176 otherwise. 177 """ 178 return False 179 180 def isupper(self): 181 """ 182 S.isupper() -> bool 183 184 Return True if all cased characters in S are uppercase and there is 185 at least one cased character in S, False otherwise. 186 """ 187 return False 188 189 def join(self, iterable): 190 """ 鏈接 """ 191 """ 192 S.join(iterable) -> string 193 194 Return a string which is the concatenation of the strings in the 195 iterable. The separator between elements is S. 196 """ 197 return "" 198 199 def ljust(self, width, fillchar=None): 200 """ 內容左對齊,右側填充 """ 201 """ 202 S.ljust(width[, fillchar]) -> string 203 204 Return S left-justified in a string of length width. Padding is 205 done using the specified fill character (default is a space). 206 """ 207 return "" 208 209 def lower(self): 210 """ 變小寫 """ 211 """ 212 S.lower() -> string 213 214 Return a copy of the string S converted to lowercase. 215 """ 216 return "" 217 218 def lstrip(self, chars=None): 219 """ 移除左側空白 """ 220 """ 221 S.lstrip([chars]) -> string or unicode 222 223 Return a copy of the string S with leading whitespace removed. 224 If chars is given and not None, remove characters in chars instead. 225 If chars is unicode, S will be converted to unicode before stripping 226 """ 227 return "" 228 229 def partition(self, sep): 230 """ 分割,前,中,後三部分 """ 231 """ 232 S.partition(sep) -> (head, sep, tail) 233 234 Search for the separator sep in S, and return the part before it, 235 the separator itself, and the part after it. If the separator is not 236 found, return S and two empty strings. 237 """ 238 pass 239 240 def replace(self, old, new, count=None): 241 """ 替換 """ 242 """ 243 S.replace(old, new[, count]) -> string 244 245 Return a copy of string S with all occurrences of substring 246 old replaced by new. If the optional argument count is 247 given, only the first count occurrences are replaced. 248 """ 249 return "" 250 251 def rfind(self, sub, start=None, end=None): 252 """ 253 S.rfind(sub [,start [,end]]) -> int 254 255 Return the highest index in S where substring sub is found, 256 such that sub is contained within S[start:end]. Optional 257 arguments start and end are interpreted as in slice notation. 258 259 Return -1 on failure. 260 """ 261 return 0 262 263 def rindex(self, sub, start=None, end=None): 264 """ 265 S.rindex(sub [,start [,end]]) -> int 266 267 Like S.rfind() but raise ValueError when the substring is not found. 268 """ 269 return 0 270 271 def rjust(self, width, fillchar=None): 272 """ 273 S.rjust(width[, fillchar]) -> string 274 275 Return S right-justified in a string of length width. Padding is 276 done using the specified fill character (default is a space) 277 """ 278 return "" 279 280 def rpartition(self, sep): 281 """ 282 S.rpartition(sep) -> (head, sep, tail) 283 284 Search for the separator sep in S, starting at the end of S, and return 285 the part before it, the separator itself, and the part after it. If the 286 separator is not found, return two empty strings and S. 287 """ 288 pass 289 290 def rsplit(self, sep=None, maxsplit=None): 291 """ 292 S.rsplit([sep [,maxsplit]]) -> list of strings 293 294 Return a list of the words in the string S, using sep as the 295 delimiter string, starting at the end of the string and working 296 to the front. If maxsplit is given, at most maxsplit splits are 297 done. If sep is not specified or is None, any whitespace string 298 is a separator. 299 """ 300 return [] 301 302 def rstrip(self, chars=None): 303 """ 304 S.rstrip([chars]) -> string or unicode 305 306 Return a copy of the string S with trailing whitespace removed. 307 If chars is given and not None, remove characters in chars instead. 308 If chars is unicode, S will be converted to unicode before stripping 309 """ 310 return "" 311 312 def split(self, sep=None, maxsplit=None): 313 """ 分割, maxsplit最多分割幾回 """ 314 """ 315 S.split([sep [,maxsplit]]) -> list of strings 316 317 Return a list of the words in the string S, using sep as the 318 delimiter string. If maxsplit is given, at most maxsplit 319 splits are done. If sep is not specified or is None, any 320 whitespace string is a separator and empty strings are removed 321 from the result. 322 """ 323 return [] 324 325 def splitlines(self, keepends=False): 326 """ 根據換行分割 """ 327 """ 328 S.splitlines(keepends=False) -> list of strings 329 330 Return a list of the lines in S, breaking at line boundaries. 331 Line breaks are not included in the resulting list unless keepends 332 is given and true. 333 """ 334 return [] 335 336 def startswith(self, prefix, start=None, end=None): 337 """ 是否起始 """ 338 """ 339 S.startswith(prefix[, start[, end]]) -> bool 340 341 Return True if S starts with the specified prefix, False otherwise. 342 With optional start, test S beginning at that position. 343 With optional end, stop comparing S at that position. 344 prefix can also be a tuple of strings to try. 345 """ 346 return False 347 348 def strip(self, chars=None): 349 """ 移除兩段空白 """ 350 """ 351 S.strip([chars]) -> string or unicode 352 353 Return a copy of the string S with leading and trailing 354 whitespace removed. 355 If chars is given and not None, remove characters in chars instead. 356 If chars is unicode, S will be converted to unicode before stripping 357 """ 358 return "" 359 360 def swapcase(self): 361 """ 大寫變小寫,小寫變大寫 """ 362 """ 363 S.swapcase() -> string 364 365 Return a copy of the string S with uppercase characters 366 converted to lowercase and vice versa. 367 """ 368 return "" 369 370 def title(self): 371 """ 372 S.title() -> string 373 374 Return a titlecased version of S, i.e. words start with uppercase 375 characters, all remaining cased characters have lowercase. 376 """ 377 return "" 378 379 def translate(self, table, deletechars=None): 380 """ 381 轉換,須要先作一個對應表,最後一個表示刪除字符集合 382 intab = "aeiou" 383 outtab = "12345" 384 trantab = maketrans(intab, outtab) 385 str = "this is string example....wow!!!" 386 print str.translate(trantab, 'xm') 387 """ 388 389 """ 390 S.translate(table [,deletechars]) -> string 391 392 Return a copy of the string S, where all characters occurring 393 in the optional argument deletechars are removed, and the 394 remaining characters have been mapped through the given 395 translation table, which must be a string of length 256 or None. 396 If the table argument is None, no translation is applied and 397 the operation simply removes the characters in deletechars. 398 """ 399 return "" 400 401 def upper(self): 402 """ 403 S.upper() -> string 404 405 Return a copy of the string S converted to uppercase. 406 """ 407 return "" 408 409 def zfill(self, width): 410 """方法返回指定長度的字符串,原字符串右對齊,前面填充0。""" 411 """ 412 S.zfill(width) -> string 413 414 Pad a numeric string S with zeros on the left, to fill a field 415 of the specified width. The string S is never truncated. 416 """ 417 return "" 418 419 def _formatter_field_name_split(self, *args, **kwargs): # real signature unknown 420 pass 421 422 def _formatter_parser(self, *args, **kwargs): # real signature unknown 423 pass 424 425 def __add__(self, y): 426 """ x.__add__(y) <==> x+y """ 427 pass 428 429 def __contains__(self, y): 430 """ x.__contains__(y) <==> y in x """ 431 pass 432 433 def __eq__(self, y): 434 """ x.__eq__(y) <==> x==y """ 435 pass 436 437 def __format__(self, format_spec): 438 """ 439 S.__format__(format_spec) -> string 440 441 Return a formatted version of S as described by format_spec. 442 """ 443 return "" 444 445 def __getattribute__(self, name): 446 """ x.__getattribute__('name') <==> x.name """ 447 pass 448 449 def __getitem__(self, y): 450 """ x.__getitem__(y) <==> x[y] """ 451 pass 452 453 def __getnewargs__(self, *args, **kwargs): # real signature unknown 454 pass 455 456 def __getslice__(self, i, j): 457 """ 458 x.__getslice__(i, j) <==> x[i:j] 459 460 Use of negative indices is not supported. 461 """ 462 pass 463 464 def __ge__(self, y): 465 """ x.__ge__(y) <==> x>=y """ 466 pass 467 468 def __gt__(self, y): 469 """ x.__gt__(y) <==> x>y """ 470 pass 471 472 def __hash__(self): 473 """ x.__hash__() <==> hash(x) """ 474 pass 475 476 def __init__(self, string=''): # known special case of str.__init__ 477 """ 478 str(object='') -> string 479 480 Return a nice string representation of the object. 481 If the argument is a string, the return value is the same object. 482 # (copied from class doc) 483 """ 484 pass 485 486 def __len__(self): 487 """ x.__len__() <==> len(x) """ 488 pass 489 490 def __le__(self, y): 491 """ x.__le__(y) <==> x<=y """ 492 pass 493 494 def __lt__(self, y): 495 """ x.__lt__(y) <==> x<y """ 496 pass 497 498 def __mod__(self, y): 499 """ x.__mod__(y) <==> x%y """ 500 pass 501 502 def __mul__(self, n): 503 """ x.__mul__(n) <==> x*n """ 504 pass 505 506 @staticmethod # known case of __new__ 507 def __new__(S, *more): 508 """ T.__new__(S, ...) -> a new object with type S, a subtype of T """ 509 pass 510 511 def __ne__(self, y): 512 """ x.__ne__(y) <==> x!=y """ 513 pass 514 515 def __repr__(self): 516 """ x.__repr__() <==> repr(x) """ 517 pass 518 519 def __rmod__(self, y): 520 """ x.__rmod__(y) <==> y%x """ 521 pass 522 523 def __rmul__(self, n): 524 """ x.__rmul__(n) <==> n*x """ 525 pass 526 527 def __sizeof__(self): 528 """ S.__sizeof__() -> size of S in memory, in bytes """ 529 pass 530 531 def __str__(self): 532 """ x.__str__() <==> str(x) """ 533 pass 534 535 str 536 537 str
5、列表
如:[11,22,33,44,55]、['wupeiqi', 'alex','solo']
一、建立列表:
1 #兩種建立方式 2 name_list = ['alex', 'seven', 'eric'] 3 4 name_list = list(['alex', 'seven', 'eric'])
二、列表類經常使用功能:
① 切片
1 name_list = ["Alex","Tenglan","Eric","Rain","Tom","Amy"] 2 print(name_list[0:3]) #取下標0至下標3之間的元素,包括0,不包括3 3 #['Alex', 'Tenglan', 'Eric'] 4 print(name_list[:3]) #:前什麼都不寫,表示從0開始,效果跟上句同樣 5 #['Alex', 'Tenglan', 'Eric'] 6 print(name_list[3:]) #:後什麼不寫,表示取值到最後 7 #['Rain', 'Tom', 'Amy'] 8 print(name_list[:]) #:先後都不寫,表示取值全部 9 #['Alex', 'Tenglan', 'Eric', 'Rain', 'Tom', 'Amy'] 10 print(name_list[-3:-1]) #從-3開始到-1,包括-3,不包括-1 11 #['Rain', 'Tom'] 12 print(name_list[1:-1]) #從1開始到-1,下標有正有負時,正數在前負數在後 13 #['Tenglan', 'Eric', 'Rain', 'Tom'] 14 print(name_list[::2]) #2表示,每一個1個元素,就取一個 15 #['Alex', 'Eric', 'Tom'] 16 #注:[-1:0] [0:0] [-1:2] 都是空
② 追加
1 name_list = ["Alex","Tenglan","Eric","Rain","Tom","Amy"] 2 name_list.append("new") #append追加,加到最後,只能添加一個 3 print(name_list) 4 #['Alex', 'Tenglan', 'Eric', 'Rain', 'Tom', 'Amy', 'new']
③ 插入
1 name_list = ["Alex","Tenglan","Eric","Rain","Tom","Amy"] 2 name_list.insert(3,"new") #insert插入,把"new"加到下標3的位置 3 print(name_list)
④ 修改
1 name_list = ["Alex","Tenglan","Eric","Rain","Tom","Amy"] 2 name_list[2] = "solo" #把下標2的字符串換成solo 3 print(name_list)
⑤ 刪除
1 #3種刪除方式 2 name_list = ["Alex","Tenglan","Eric","Rain","Tom","Amy"] 3 del name_list[3] #del刪除,指定要刪除的下標 4 print(name_list) 5 #['Alex', 'Tenglan', 'Eric', 'Tom', 'Amy'] 6 name_list.remove("Tenglan") #remove刪除,指定要刪除的字符 7 print(name_list) 8 #['Alex', 'Eric', 'Tom', 'Amy'] 9 name_list.pop() #pop刪除,刪除列表最後一個值 10 print(name_list) 11 #['Alex', 'Eric', 'Tom']
⑥ 擴展
1 name_list = ["Alex","Tenglan","Eric","Rain","Tom","Amy"] 2 age_list = [11,22,33] 3 name_list.extend(age_list) #extend擴展,把列表age_list添加到name_list列表 4 print(name_list)
⑦ 拷貝
1 name_list = ["Alex","Tenglan","Eric","Rain","Tom","Amy"] 2 copy_list = name_list.copy() #copy拷貝,對列表進行復制 3 print(copy_list) 4 #注:以後會整理深淺copy的詳細區分
⑧ 統計
1 name_list = ["Alex","Tenglan","Eric","Amy","Tom","Amy"] 2 print(name_list.count("Amy")) #count統計,統計列表Amy的個數 3 #2
⑨ 排序和翻轉
1 name_list = ["Alex","Tenglan","Eric","Rain","Tom","Amy","1","2","3"] 2 name_list.sort() #sort排序,對列表進行排序 3 print(name_list) 4 #['1', '2', '3', 'Alex', 'Amy', 'Eric', 'Rain', 'Tenglan', 'Tom'] 5 name_list.reverse() #reverse翻轉,對列表進行翻轉 6 print(name_list) 7 #['Tom', 'Tenglan', 'Rain', 'Eric', 'Amy', 'Alex', '3', '2', '1']
⑩ 獲取下標
1 name_list = ["Alex","Tenglan","Eric","Rain","Tom","Amy"] 2 print(name_list.index("Tenglan")) #index索引,獲取字符的下標 3 #1
6、元組
如:(11,22,33,44,55)、('wupeiqi', 'alex','lzl')
1、建立元組:
1 #5種建立方式 2 age = 11,22,33,44,55 #直接寫數字或者字符串,默認建立類型元組 字符串類型用引號'solo' 3 #輸出: (11, 22, 33, 44, 55) 4 age = (11,22,33,44,55) #常見命名方式,()指定類型元組 5 #輸出: (11, 22, 33, 44, 55) 6 age = tuple((11,22,33,44,55)) #tuple 以類的方式建立(()) 雙括號 裏面的()不可去掉 7 #輸出: (11, 22, 33, 44, 55) 8 age = tuple([11,22,33,44,55]) #同(()) 效果同樣 不多用 忘記它 9 #輸出: (11, 22, 33, 44, 55) 10 age = tuple({11,22,33,44,55}) #({})建立的元組,隨機排列 沒卵用 11 #輸出: (33, 11, 44, 22, 55)
二、元組類經常使用功能:
1 ##count #統計元組字符出現的次數 2 name = ('wupeiqi', 'alex','solo') 3 print(name.count('alex')) 4 # 1 5 ##index #查看字符串所在的索引位置 6 name = ('wupeiqi', 'alex','solo') 7 print(name.index('solo')) 8 # solo
7、字典 無序
如:{'name': 'wupeiqi', 'age': 18} 、{'host': 'solo.solo.solo.solo', 'port': 80}
注:字典一種key:value 的數據類型,也稱鍵值對。字典dict是無序的,key值必須是惟一的,不能有重複。循環時,默認循環的是key
一、建立字典
1 #兩種建立方式: 2 info_dic = {'stu1101': "TengLan Wu",'stu1102': "LongZe Luola",'stu1103': "XiaoZe Maliya",} 3 print(info_dic) 4 #{'stu1102': 'LongZe Luola', 'stu1101': 'TengLan Wu', 'stu1103': 'XiaoZe Maliya'} 5 info_dic = dict({'stu1101': "TengLan Wu",'stu1102': "LongZe Luola",'stu1103': "XiaoZe Maliya",}) 6 print(info_dic) 7 #{'stu1102': 'LongZe Luola', 'stu1101': 'TengLan Wu', 'stu1103': 'XiaoZe Maliya'}
2、字典類經常使用功能:
① 增長
1 info_dic = {'stu1101': "TengLan Wu",'stu1102': "LongZe Luola",'stu1103': "XiaoZe Maliya",} 2 info_dic['stu1104'] = "JingKong Cang" #增長 3 print(info_dic)
② 修改
1 info_dic = {'stu1101': "TengLan Wu",'stu1102': "LongZe Luola",'stu1103': "XiaoZe Maliya",} 2 info_dic["stu1101"] = "Jingkong Cang" #有相應的key時爲修改,沒有爲增長 3 print(info_dic)
③ 刪除
1 #3種刪除方式 2 info_dic = {'stu1101': "TengLan Wu",'stu1102': "LongZe Luola",'stu1103': "XiaoZe Maliya",} 3 info_dic.pop('stu1101') #pop刪除,指定刪除的key 4 print(info_dic) 5 #{'stu1103': 'XiaoZe Maliya', 'stu1102': 'LongZe Luola'} 6 del info_dic['stu1102'] #del刪除,指定刪除的key 7 print(info_dic) 8 #{'stu1103': 'XiaoZe Maliya'} 9 info_dic = {'stu1101': "TengLan Wu",'stu1102': "LongZe Luola",'stu1103': "XiaoZe Maliya",} 10 info_dic.popitem() #隨機刪除,沒卵用 11 print(info_dic) 12 #{'stu1101': 'TengLan Wu', 'stu1103': 'XiaoZe Maliya'}
④ 查找value值
1 info_dic = {'stu1101': "TengLan Wu",'stu1102': "LongZe Luola",'stu1103': "XiaoZe Maliya",} 2 print(info_dic.get('stu1102')) #get查找,經過key查找value值 3 #LongZe Luola 4 print(info_dic['stu1102']) #經過key直接查找,可是若是輸入查找的key不存在的話,就會報錯,get則不會 5 #LongZe Luola
⑤ 字典多級嵌套
1 av_catalog = { 2 "歐美":{ 3 "www.youporn.com": ["不少免費的,世界最大的","質量通常"], 4 "www.pornhub.com": ["不少免費的,也很大","質量比yourporn高點"], 5 "letmedothistoyou.com": ["可能是自拍,高質量圖片不少","資源很少,更新慢"], 6 "x-art.com":["質量很高,真的很高","所有收費,屌比請繞過"] 7 }, 8 "日韓":{ 9 "tokyo-hot":["質量怎樣不清楚,我的已經不喜歡日韓範了","據說是收費的"] 10 }, 11 "大陸":{ 12 "1024":["所有免費,真好,好人一輩子平安","服務器在國外,慢"] 13 } 14 } 15 16 av_catalog["大陸"]["1024"][1] += ",能夠用爬蟲爬下來" 17 print(av_catalog["大陸"]["1024"]) 18 #['所有免費,真好,好人一輩子平安', '服務器在國外,慢,能夠用爬蟲爬下來']
⑥ 循環
1 info_dic = {'stu1101': "TengLan Wu",'stu1102': "LongZe Luola",'stu1103': "XiaoZe Maliya",} 2 for stu_nu in info_dic: 3 print(stu_nu,info_dic[stu_nu]) #循環默認提取的是key 4 #stu1103 XiaoZe Maliya 5 #stu1101 TengLan Wu 6 #stu1102 LongZe Luola 7 for k,v in info_dic.items(): #先把dict生成list,數據量大的時候費時,不建議使用 8 print(k,v) 9 #stu1103 XiaoZe Maliya 10 #stu1101 TengLan Wu 11 #stu1102 LongZe Luola
8、集合
如:{'solo', 33, 'alex', 22, 'eric', 'wupeiqi', 11}
注:集合是一個無序的,不重複的數據組合。去重性,把一個列表變成集合,就自動去重了。關係測試,測試兩組數據以前的交集、差集、並集
一、建立集合
1 #標準建立方式 2 info_set = set(["alex","wupeiqi","eric","solo",11,22,33]) 3 print(info_set,type(info_set)) 4 #{33, 11, 'wupeiqi', 'solo', 'alex', 'eric', 22} <class 'set'>
二、集合類經常使用功能
① 添加
1 #添加的兩種方式 2 set_1 = set(["alex","wupeiqi","eric","solo"]) 3 set_1.add(11) #add只能添加一個元素 4 print(set_1) 5 #{'alex', 'solo', 'eric', 11, 'wupeiqi'} 6 set_1 = set(["alex","wupeiqi","eric","solo"]) 7 set_1.update([11,22,33]) 8 print(set_1) #update能夠添加多個元素 9 #{33, 11, 'alex', 'wupeiqi', 'eric', 22, 'solo'}
② 刪除
1 #刪除的三種方式 2 set_1 = set(["alex","wupeiqi","eric","solo",11,22,33]) 3 set_1.remove("alex") #remove 刪除指定元素 4 print(set_1) 5 #{'eric', 33, 'solo', 11, 22, 'wupeiqi'} 6 set_1.pop() #pop 隨機刪除元素 7 print(set_1) 8 #{33, 'wupeiqi', 11, 22, 'solo'} 9 set_1.discard("solo") #discard 刪除指定元素,與remove區別在於,若是元素不存在也不會報錯 10 set_1.discard(55) 11 print(set_1) 12 #{33, 'wupeiqi', 11, 22}
三、集合關係測試
① 交集
1 set_1 = set(["alex","wupeiqi","eric","solo",11,22,33]) 2 set_2 = set([11,22,33,44,55,66]) 3 print(set_1.intersection(set_2)) #intersection 取兩個set的交集 set_1和set_2能夠互換位置 4 #{33, 11, 22}
② 並集
1 set_1 = set(["alex","wupeiqi","eric","solo",11,22,33]) 2 set_2 = set([11,22,33,44,55,66]) 3 print(set_1.union(set_2)) #union 取兩個set集合的並集 set_1和set_2能夠互換位置 4 #{33, 66, 11, 44, 'eric', 55, 'solo', 22, 'wupeiqi', 'alex'}
③ 差集
1 set_1 = set(["alex","wupeiqi","eric","solo",11,22,33]) 2 set_2 = set([11,22,33,44,55,66]) 3 print(set_1.difference(set_2)) #difference 取兩個set集合的差集 set_1有可是set_2沒有的集合 4 #{'solo', 'eric', 'wupeiqi', 'alex'}
④ 子集、父集
1 set_1 = set(["alex","wupeiqi","eric","solo",11,22,33]) 2 set_2 = set([11,22,33,44,55,66]) 3 set_3 = set([11,22,33]) 4 print(set_1.issubset(set_2)) #issubset 子集 5 #False 6 print(set_1.issuperset(set_3)) #issuperset 父集 7 #True
⑤ 對稱差集
1 set_1 = set(["alex","wupeiqi","eric","solo",11,22,33]) 2 set_2 = set([11,22,33,44,55,66]) 3 print(set_1.symmetric_difference(set_2)) #symmetric_difference 對稱差集=兩個集合並集減去合集 4 #{66, 'solo', 'eric', 'alex', 55, 'wupeiqi', 44}
⑥ 運算符作關係測試
1 set_1 = set(["alex","wupeiqi","eric","solo",11,22,33]) 2 set_2 = set([11,22,33,44,55,66]) 3 set_union = set_1 | set_2 # 並集 4 set_intersection = set_1 & set_2 # 交集 5 set_difference = set_1 - set_2 # 差集 6 set_symmetric_difference = set_1 ^ set_2 # 對稱差集
6、模塊初識
Python有大量的模塊,從而使得開發Python程序很是簡潔。類庫有包括三中:
① 、Python內部提供的模塊
②、業內開源的模塊
③、程序員本身開發的模塊:Python腳本的名字不要與模塊名相同
一、sys模塊(系統內置)
① sys.argv 用來捕獲執行python腳本時傳入的參數
② sys.stdin 標準信息輸入
③ sys.stdout 標準定向輸出
④ sys.stdout.flush 強制刷新標準輸出緩存
1 import time 2 import sys 3 for i in range(5): 4 print(i), 5 sys.stdout.flush() 6 time.sleep(1) 7 # 這樣設計是爲了打印一個數每秒五秒鐘,但若是您運行它,由於它是如今(取決於您的默認系統緩衝), 8 # 你可能看不到任何輸出 CodeGo.net,直到再一次所有,你會看到0 1 2 3 4打印到屏幕上。 9 # 這是輸出被緩衝,除非你sys.stdout以後每print你不會看到從輸出中取出sys.stdout.flush()網上看到的差異
二、os模塊(與系統進行交互)
① os.dir、os.popen調用當前系統命令
三、platform模塊(識別當前運行的系統)
7、運算符
一、算數運算:
二、比較運算:
三、賦值運算:
四、邏輯運算:
五、成員運算:
六、身份運算:
七、位運算:
八、運算符優先級:
8、深淺拷貝剖析
一、對象賦值(建立列表變量Alex,變量包含子列表,經過變量Alex給變量solo賦值,而後對變量Alex的元素進行修改,此時solo會有什麼變化呢?)
1 import copy #import調用copy模塊 2 3 Alex = ["Alex", 28, ["Python", "C#", "JavaScript"]] 4 solo = Alex #直接賦值 5 6 # 修改前打印 7 print(id(Alex)) 8 print(Alex) 9 print([id(adr) for adr in Alex]) 10 # 輸出: 7316664 11 # ['Alex', 28, ['Python', 'C#', 'JavaScript']] 12 # [2775776, 1398430400, 7318024] 13 print(id(solo)) 14 print(solo) 15 print([id(adr) for adr in solo]) 16 # 輸出: 7316664 17 # ['Alex', 28, ['Python', 'C#', 'JavaScript']] 18 # [2775776, 1398430400, 7318024] 19 20 # 對變量進行修改 21 Alex[0]='Mr.Wu' 22 Alex[2].append('CSS') 23 print(id(Alex)) 24 print(Alex) 25 print([id(adr) for adr in Alex]) 26 # 輸出: 7316664 27 # ['Mr.Wu', 28, ['Python', 'C#', 'JavaScript', 'CSS']] 28 # [5170528, 1398430400, 7318024] 29 print(id(solo)) 30 print(solo) 31 print([id(adr) for adr in solo]) 32 # 輸出: 7316664 33 # ['Mr.Wu', 28, ['Python', 'C#', 'JavaScript', 'CSS']] 34 # [5170528, 1398430400, 7318024]
初始條件: Alex = ["Alex", 28, ["Python", "C#", "JavaScript"]]
對象賦值: solo = Alex #直接賦值
對象賦值結果:solo = ["Alex", 28, ["Python", "C#", "JavaScript"]]
對象賦值時是進行對象引用(內存地址)的傳遞,被賦值的變量並無開闢新內存,兩個變量共用一個內存地址
修改對象賦值:solo = ['Mr.Wu', 28, ['Python', 'C#', 'JavaScript', 'CSS']]
str是不可變類型,因此當修改元素Alex爲Mr.Wu時,內存地址發生改變;list是可變類型,元素['Python', 'C#', 'JavaScript', 'CSS']修改完後,內存地址沒有改變
二、淺拷貝(建立列表變量Alex,變量包含子列表,經過copy模塊的淺拷貝函數copy()對變量Alex進行拷貝,當對Alex進行操做時,此時solo會如何變化?)
1 import copy #import調用copy模塊 2 Alex = ["Alex", 28, ["Python", "C#", "JavaScript"]] 3 solo = copy.copy(Alex) #經過copy模塊裏面的淺拷貝函數copy() 4 # 修改前打印 5 print(id(Alex)) 6 print(Alex) 7 print([id(adr) for adr in Alex]) 8 # 輸出: 10462472 9 # ['Alex', 28, ['Python', 'C#', 'JavaScript']] 10 # [5462752, 1359960768, 10463232] 11 print(id(solo)) 12 print(solo) 13 print([id(adr) for adr in solo]) 14 # 輸出: 10201848 15 # ['Alex', 28, ['Python', 'C#', 'JavaScript']] 16 # [5462752, 1359960768, 10463232] 17 # 對變量進行修改 18 Alex[0]='Mr.Wu' 19 Alex[2].append('CSS') 20 print(id(Alex)) 21 print(Alex) 22 print([id(adr) for adr in Alex]) 23 # 輸出: 10462472 24 # ['Mr.Wu', 28, ['Python', 'C#', 'JavaScript', 'CSS']] 25 # [10151264, 1359960768, 10463232] 26 print(id(solo)) 27 print(solo) 28 print([id(adr) for adr in solo]) 29 # 輸出: 10201848 30 # ['Alex', 28, ['Python', 'C#', 'JavaScript', 'CSS']] 31 # [5462752, 1359960768, 10463232]
初始條件: Alex = ["Alex", 28, ["Python", "C#", "JavaScript"]]
淺拷貝: solo = copy.copy(Alex) #經過copy模塊裏面的淺拷貝函數copy()
淺拷貝結果: solo = ["Alex", 28, ["Python", "C#", "JavaScript"]]
淺拷貝時變量solo新建了一塊內存(10201848),此內存記錄了list中元素的地址;對於list中的元素,淺拷貝會使用原始元素的引用(內存地址)
修改淺拷貝: solo = ['Mr.Wu', 28, ['Python', 'C#', 'JavaScript', 'CSS']]
str是不可變類型,因此當修改元素Alex爲Mr.Wu時,內存地址發生改變;list是可變類型,元素['Python', 'C#', 'JavaScript', 'CSS']修改完後,內存地址沒有改變
三、深拷貝(建立列表變量Alex,變量包含子列表,經過copy模塊的深拷貝函數deepcopy()對變量Alex進行拷貝,當對Alex進行操做時,此時solo會如何變化?)
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 #-Author-Lian 4 # 深拷貝 5 import copy #import調用copy模塊 6 7 Alex = ["Alex", 28, ["Python", "C#", "JavaScript"]] 8 solo = copy.deepcopy(Alex) #經過copy模塊裏面的深拷貝函數deepcopy() 9 10 # 修改前打印 11 print(id(Alex)) 12 print(Alex) 13 print([id(adr) for adr in Alex]) 14 # 輸出: 6202712 15 # ['Alex', 28, ['Python', 'C#', 'JavaScript']] 16 # [4086496, 1363237568, 6203472] 17 print(id(solo)) 18 print(solo) 19 print([id(adr) for adr in solo]) 20 # 輸出: 6203032 21 # ['Alex', 28, ['Python', 'C#', 'JavaScript']] 22 # [4086496, 1363237568, 6203512] 23 24 # 對變量進行修改 25 Alex[0]='Mr.Wu' 26 Alex[2].append('CSS') 27 print(id(Alex)) 28 print(Alex) 29 print([id(adr) for adr in Alex]) 30 # 輸出: 6202712 31 # ['Mr.Wu', 28, ['Python', 'C#', 'JavaScript', 'CSS']] 32 # [5236064, 1363237568, 6203472] 33 print(id(solo)) 34 print(solo) 35 print([id(adr) for adr in solo]) 36 # 輸出: 6203032 37 # ['Alex', 28, ['Python', 'C#', 'JavaScript']] 38 # [4086496, 1363237568, 6203512]
初始條件: Alex = ["Alex", 28, ["Python", "C#", "JavaScript"]]
深拷貝: solo = copy.deepcopy(Alex) #經過copy模塊裏面的深拷貝函數deepcopy()
深拷貝結果: solo = ["Alex", 28, ["Python", "C#", "JavaScript"]]
深拷貝時變量solo新建了一塊內存(10201848),此內存記錄了list中元素的地址;可是,對於list中第三個元素(['Python', 'C#', 'JavaScript'])從新生成了一個地址(6203512),此時兩個變量的第三個元素的內存引用地址不一樣
修改深拷貝: solo = ['Mr.Wu', 28, ['Python', 'C#', 'JavaScript', 'CSS']]
str是不可變類型,因此當修改元素Alex爲Mr.Wu時,內存地址發生改變;list是可變類型,元素['Python', 'C#', 'JavaScript', 'CSS']修改完後,內存地址沒有改變,可是Alex和solo在第三個元素引用的本就不一樣
四、對於拷貝有一些特殊狀況
(1)對於非容器類型(如數字、字符串、和其餘'原子'類型的對象)沒有拷貝這一說
(2)也就是說,對於這些類型,"obj is copy.copy(obj)" 、"obj is copy.deepcopy(obj)"
(3)若是元祖變量只包含原子類型對象,則不能深拷貝
①爲何要拷貝?
答:當進行修改時,想要保留原來的數據和修改後的數據
②數字字符串 和 集合 在修改時的差別? (深淺拷貝不一樣的終極緣由)
答:在修改數據時:
數字字符串:在內存中新建一份數據
集合:修改內存中的同一份數據
③對於集合,如何保留其修改前和修改後的數據?
答:在內存中拷貝一份
④對於集合,如何拷貝其n層元素同時拷貝?
答:深拷貝
9、文件操做
(1)打開文件: 文件句柄 = file('文件路徑', '模式')
python中打開文件有兩種方式,即:open(...) 和 file(...) ,本質上前者在內部會調用後者來進行文件操做,推薦使用 open。
一、打開文件的模式:
r, 只讀模式【默認】
w,只寫模式【不可讀;不存在則建立;存在則刪除內容;】
a, 追加模式【不可讀;不存在則建立;存在則只追加內容;】
二、"+" 同時讀寫某個文件:
r+,可讀寫文件。【可讀;可寫;可追加】
w+,寫讀
a+,追加讀
1 總結1:r+模式下,若是在.write()進行寫入內容前,有print()輸出,則要寫的內容會從文件尾部開始寫入,使用的是讀、追加模式;若是在.write()進行寫入內容前,是seek()移動光標,則要寫的內容會從移動到的光標開始進行寫入,會把原來的內容覆蓋掉,而不是總體後移,這點要記住;若是在.write()進行寫入內容前,既沒有print()也沒有seek()光標移動,這種狀況以前想的的狀況,就是r+讀寫模式能先寫後讀嗎?r+模式下默認光標在文件的首部,此時會直接從文件開頭進行寫入,效果等同於seek(0)。關於最後一點,參考a+模式。 2 總結2:讀寫模式必定要先寫後讀嗎?能不能先讀後寫? 若是先讀的話,因爲用的是w+模式打開的文件,打開後會清空原文件內容,全部讀取的到東西是空的。另W+模式後期用的不多,瞭解便可,包括a+追加讀這種模式;另w+模式下,光標會跟隨文件寫入移到到文件末尾,不用seek移到光標的話,打印內容爲空 3 注:w+模式下,關於.write()跟seek()和print()的關係與r+模式下是同樣同樣的。w+打開文件後先清空,而後追加寫,若是.write()前有seek()的話會從光標位置覆蓋寫。 4 總結3:經過上面的程序能夠得出,a+模式下光標位置爲文件末尾,若是要print()的話要結合seek()進行使用;另外與r+、w+不一樣的是,.write()與seek()沒有關係,只能寫內容到文件末尾,一直都是追加模式!
三、"U"表示在讀取時,能夠將 \r \n \r\n自動轉換成 \n (與 r 或 r+ 模式同使用)
rU
r+U
四、"b"表示處理二進制文件(如:FTP發送上傳ISO鏡像文件,linux可忽略,windows處理二進制文件時需標註)
rb 二進制讀
wb 二進制寫(ab也同樣)
ab
(2)文件操做經常使用功能:
一、read()、readline()、readlines()的區別
print(info_file.read()) #read參數,讀取文件全部內容
print(info_file.readline()) #readline,只讀取文章中的一行內容
print(info_file.readlines()) #readlines,把文章內容以換行符分割,並生成list格式,數據量大的話不建議使用
二、seek、tell光標
data = info_file.read() #默認光標在起始位置,.read()讀取完後,光標停留到文件末尾
print(info_file.tell()) #tell 獲取當前的光標位
info_file.seek(0) #seek 移動光標到文件首部
三、文件循環
for index,line in enumerate(info_file.readlines()): #先把文件內容以行爲分割生成列表,數據量大不能用
for line in info_file: #建議使用方法,每讀取一行,內存會把以前的空間清空,不會佔用太多內存
四、flush 刷新
sys.stdout.flush() #flush 強制刷新緩存到內存的數據寫入硬盤
五、truncate 截斷
truncate跟光標位置無關,從文件首部開始截取字符;若是是truncate(0)會把文件清空
六、with 語句
爲了不打開文件後忘記關閉,能夠經過管理上下文,即:
with open('log','r') as f:
...
如此方式,當with代碼塊執行完畢時,內部會自動關閉並釋放文件資源。在Python 2.7 後,with又支持同時對多個文件的上下文進行管理,即:
with open('log1') as obj1, open('log2') as obj2:
pass
(3)文件修改方式:
一、把文件讀取到內存當中,對內存進行修改,把修改後的內容寫入到原文件(舊內容被清空)
二、若是在硬盤上直接寫,會進行覆蓋,硬盤上不能進行插入,原來的內容不會總體後移,而是直接覆蓋掉
三、把文件讀取到內存當中,對內存進行修改,把修改的內容另存爲新的文件(舊文件保留)
① 另存方式
② r+模式
③ a+模式
10、函數
①格式
1 def 函數名(參數): 2 .... 3 函數體 4 .... 5 return 返回值 6 函數名()
②形參: def func(name): // name 叫作函數func的形式參數,簡稱:形參
③實參: func("solo") // 'solo' 叫作函數func的實際參數,簡稱:實參
④默認參數: def stu_register(name,age,course,country="CN") // 位置參數
⑤關鍵參數: stu_register(age=22,name='lzl',course="python") // 關鍵參數必須放在位置參數以後
形參:在定義函數時,括號內的參數成爲形參 特色:形參就是變量名 # def foo(x,y): #x=1,y=2 # print(x) # print(y) 實參:在調用函數時,括號內的參數成爲實參 特色:實參就是變量值 # foo(1,2) 在調用階段實參(變量值)纔會綁定形參(變量名) 調用結束後,解除綁定 參數的分類 位置參數:按照從左到右的順序依次定義的參數 位置形參:必須被傳值,而且多一個不行,少一個也不行 位置實參:與形參按照位置一一對應 # def foo(x,y): # print(x) # print(y) # # foo('egon',1,2) 關鍵字實參:指的是按照name=value的形式,指名道姓地給name傳值 # def foo(name,age): # print(name) # print(age) # foo('egon',18) # foo(age=18,name='egon') 關鍵字實參須要注意的問題是: # def foo(name,age,sex): # print(name) # print(age) # print(sex) # foo('egon',18,'male') # print('======>') # foo(sex='male',age=18,name='egon') # foo('egon',sex='male',age=18) 問題一:語法規定位置實參必須在關鍵字實參的前面 # foo('egon',sex='male',age=18) 問題二:必定不要對同一個形參傳屢次值 # foo('egon',sex='male',age=18,name='egon1') # foo('male',age=18,name='egon1') 默認參數(默認形參):在定義階段,就已經爲形參賦值,意味在調用階段能夠不用傳值 # def foo(x,y=1111111): # print(x) # print(y) # # # foo(1,'a') # # def register(name,age,sex='male'): # print(name,age,sex) # # # register('asb',73) # register('wsb',38) # register('ysb',84) # register('yaya',28,'female') 默認參數須要注意的問題 問題一:默認參數必須放在位置參數以後 # def foo(y=1,x): # print(x,y) 問題二:默認參數只在定義階段賦值一次,並且僅一次 # x=100 # def foo(a,b=x): # print(a,b) # # x=111111111111111111111111111111 # foo('egon' 問題三:默認參數的值應該定義成不可變類型 #可變長參數指的是實參的個數多了 #實參無非位置實參和關鍵字實參兩種 #形參必需要兩種機制來分別處理按照位置定義的實參溢出的狀況:* #跟按照關鍵字定義的實參溢出的狀況:** # def foo(x,y,*args): #nums=(3,4,5,6,7) # print(x) # print(y) # print(args) # foo(1,2,3,4,5,6,7) #* # foo(1,2) #* #*args的擴展用法 # def foo(x,y,*args): #*args=*(3,4,5,6,7) # print(x) # print(y) # print(args) # # # foo(1,2,3,4,5,6,7) #* # # # foo(1,2,*(3,4,5,6,7)) #foo(1,2,3,4,5,6,7) # def foo(x,y=1,*args): # # print(x) # print(y) # print(args) # # # foo('a','b',*(1,2,3,4,5,6,7)) #foo('a','b',1,2,3,4,5,6,7) # # foo('egon',10,2,3,4,5,6,9,y=2) #報錯 # foo('egon',10,2,3,4,5,6,9) # def foo(x,y,**kwargs): #nums={'z':3,'b':2,'a':1} # print(x) # print(y) # print(kwargs) # foo(1,2,z=3,a=1,b=2) #** # def foo(x,y,**kwargs): #kwargs={'z':3,'b':2,'a':1} # print(x) # print(y) # print(kwargs) # # foo(1,2,**{'z':3,'b':2,'a':1}) #foo(1,2,a=1,z=3,b=2) # def foo(x, y): # # print(x) # print(y) # # foo(**{'y':1,'x':2}) # foo(y=1,x=2) # def foo(x,*args,**kwargs):#args=(2,3,4,5) kwargs={'b':1,'a':2} # print(x) # print(args) # print(kwargs) # # # foo(1,2,3,4,5,b=1,a=2) #這倆東西*args,**kwargs幹甚用??? def register(name,age,sex='male'): print(name) print(age) print(sex) # def wrapper(*args,**kwargs): #args=(1,2,3) kwargs={'a':1,'b':2} # # print(args) # # print(kwargs) # register(*args,**kwargs) # # register(*(1, 2, 3),**{'a': 1, 'b': 2}) # # register(1, 2, 3,a=1,b=2) # # # wrapper(1,2,3,a=1,b=2) import time # def register(name,age,sex='male'): # # start_time=time.time() # print(name) # print(age) # print(sex) # time.sleep(3) # stop_time=time.time() # print('run time is %s' %(stop_time-start_time)) # def wrapper(*args, **kwargs): #args=('egon',) kwargs={'age':18} # start_time=time.time() # register(*args, **kwargs) # stop_time=time.time() # print('run time is %s' %(stop_time-start_time)) # # # wrapper('egon',age=18) # register('egon',18) #命名關鍵字參數: 在*後面定義的形參稱爲命名關鍵字參數,必須是被以關鍵字實參的形式傳值 # def foo(name,age,*args,sex='male',group): # print(name) # print(age) # print(args) # print(sex) # print(group) # # foo('alex',18,19,20,300,group='group1') def foo(name,age=18,*args,sex='male',group,**kwargs): pass
⑥動態參數/非固定參數(*args 和 **kwargs):
1 (1)*args:*args會把多傳入的實參變成一個元組的類型;即便傳入的是list類型也會變成元組,成爲元組中的一個元素;另函數中有*args與其餘形參的時候,*args必定要寫到其 他形參的後面,不然傳入的實參都會被傳入到*args當中打印成元組;還有若是沒有多出傳入的實參即*args沒有值的時候,*args爲空,不會報錯。 2 (2)**kwargs:**kwargs會把多出的a=b這種類型的實參打印成字典的類型(要區分開與關鍵參數的區別,關鍵參數的實參有對應的形參),被當成多餘的實參傳入到了*args裏面,因此**kwargs的值才爲空,分別用*inf_list和**info_dict的方式傳入到*args、**kwargs當中(stu_register("lzl",*info_list,**info_dict) //傳入列表和字典) 3 總結:*args必須放到**kwargs前面(規定);位置參數必定要放到關鍵參數以前(規定);默認參數不能跟*args、**kwargs一塊存在(會報錯)。
⑦return 返回值: 若是不執行return,函數的默認返回值爲None;當函數執行到return時,函數結束執行
⑧局部變量: name = "Alex Li" #定義變量name
1 def change_name(name): 2 name = "金角大王,一個有Tesla的男人" #函數內部更改變量 3 函數內部對變量進行更改後,生效範圍僅限於函數內部,對外部變量沒有影響,這種變量稱爲局部變量;函數內部也可讓變量全局生效,須要加參數global,這種狀況不多用。
⑨遞歸函數: 若是一個函數在內部調用自身自己,這個函數就是遞歸函數
條件: 有結束條件、更深一層遞歸規模比上次遞歸有所減小、效率不高,遞歸層次過多會致使棧溢出
1 寫一個遞歸: 2 def func(n1,n2): #獲取斐波那契數列100以前的數字 3 if n1 > 100: 4 return 5 print(n1) 6 n3 = n1 + n2 7 func(n2,n3) 8 func(0,1)
⑩匿名函數:不須要顯式的指定函數
1 #普通函數 #換成匿名函數 2 def calc(n): calc = lambda n:n**n 3 return n**n print(calc(10) 4 print(calc(10))
⑪高階函數: 變量能夠指向函數,函數的參數能接收變量,那麼一個函數就能夠接收另外一個函數做爲參數,這種函數就稱之爲高階函數。
1 def add(x,y,f): 2 return f(x) + f(y) 3 res = add(3,-6,abs) 4 print(res)
⑫內置函數
⑬函數的調用順序:被調用函數要在執行以前被定義
1 #函數錯誤的調用方式 2 def func(): #定義函數func() 3 print("in the func") 4 foo() #調用函數foo() 5 func() #執行函數func() 6 def foo(): #定義函數foo() 7 print("in the foo") 8 9 #函數正確的調用方式 10 def func(): #定義函數func() 11 print("in the func") 12 foo() #調用函數foo() 13 def foo(): #定義函數foo() 14 print("in the foo") 15 func() #執行函數func()
⑭高階函數:一、某一函數當作參數傳入另外一個函數中。二、函數的返回值包含一個或多個函數
⑮內嵌函數:在一個函數體內建立另一個函數(內嵌函數中定義的函數在全局中是沒法直接執行的)
⑯裝飾器:本質是函數(裝飾其餘函數),爲其餘函數添加附加功能的。
遵循原則: 1.不能修改被裝飾函數的源代碼 2.不能修改被裝飾函數的調用方式
組成:裝飾器由高階函數+內嵌函數組成
⑰生成器:調用時纔會生成相應數據的機制,稱爲生成器:generator
應用:可經過yield實如今單線程的狀況下實現併發運算的效果(協程)
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 #-Author-solo 4 import time 5 def consumer(name): 6 print("%s 準備吃包子啦!" %name) 7 while True: 8 baozi = yield #yield的做用:保存當前狀態並返回 9 10 print("包子[%s]來了,被[%s]吃了!" %(baozi,name)) 11 def producer(name): 12 c = consumer('A') 13 c2 = consumer('B') 14 c.__next__() #c.__next__()等同於next(c) 15 c2.__next__() #next()做用:調用yield,不給yield傳值 16 print("老子開始準備作包子啦!") 17 for i in range(10): 18 time.sleep(1) 19 print("%s作了2個包子!"%(name)) 20 c.send(i) #send()做用:調用yield,給yield傳值 21 c2.send(i) 22 producer("solo")
⑱迭代器
可迭代對象:能夠直接做用於for循環的對象:Iterable
能夠直接做用於for循環的數據類型有:一、集合數據類型,如list、tuple、dict、set、str等;二、生成器,包括generator和帶yield的generator function;
能夠用isinstance()去判斷一個對象是不是Iterable對象
from collections import Iterable
print(isinstance([], Iterable))
# True
迭代器:能夠被next()函數調用並不斷返回下一個值的對象稱爲迭代器:Iterator。
用isinstance()判斷一個對象是不是Iterator對象
from collections import Iterator
print(isinstance([], Iterator))
# True
小結:
一、凡是可做用於for循環的對象都是Iterable類型;
二、凡是可做用於next()函數的對象都是Iterator類型,它們表示一個惰性計算的序列;
三、集合數據類型如list、dict、str等是Iterable但不是Iterator,不過能夠經過iter()函數得到一個Iterator對象;
四、Python的for循環本質上就是經過不斷調用next()函數實現的
1 for x in [1, 2, 3, 4, 5]: 2 pass
1 首先得到Iterator對象: 2 it = iter([1, 2, 3, 4, 5]) 3 # 循環: 4 while True: 5 try: 6 # 得到下一個值: 7 x = next(it) 8 except StopIteration: 9 # 遇到StopIteration就退出循環 10 break
11、經常使用模塊
(一)、導入模塊:導入模塊的本質就是把python文件解釋一遍;導入包的本質就是把包文件下面的init.py文件運行一遍
(二)、經常使用模塊:
(1)time和datatime模塊
時間相關的操做,時間有三種表示方式:一、時間戳 1970年1月1日以後的秒,即:time.time()
二、格式化的字符串 2014-11-11 11:11, 即:time.strftime('%Y-%m-%d')
三、結構化時間 元組包含了:年、日、星期等... time.struct_time 即:time.localtime()
1 import time 2 print(time.time()) #時間戳 3 #1472037866.0750718 4 print(time.localtime()) #結構化時間 5 #time.struct_time(tm_year=2016, tm_mon=8, tm_mday=25, tm_hour=8, tm_min=44, tm_sec=46, tm_wday=3, tm_yday=238, tm_isdst=0) 6 print(time.strftime('%Y-%m-%d')) #格式化的字符串 7 #2016-08-25 8 print(time.strftime('%Y-%m-%d',time.localtime())) 9 #2016-08-25 10 print(time.gmtime()) #結構化時間 11 #time.struct_time(tm_year=2016, tm_mon=8, tm_mday=25, tm_hour=3, tm_min=8, tm_sec=48, tm_wday=3, tm_yday=238, tm_isdst=0) 12 print(time.strptime('2014-11-11', '%Y-%m-%d')) #結構化時間 13 #time.struct_time(tm_year=2014, tm_mon=11, tm_mday=11, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=1, tm_yday=315, tm_isdst=-1) 14 print(time.asctime()) 15 #Thu Aug 25 11:15:10 2016 16 print(time.asctime(time.localtime())) 17 #Thu Aug 25 11:15:10 2016 18 print(time.ctime(time.time())) 19 #Thu Aug 25 11:15:10 2016
1 import datetime 2 print(datetime.date) #表示日期的類。經常使用的屬性有year, month, day 3 #<class 'datetime.date'> 4 print(datetime.time) #表示時間的類。經常使用的屬性有hour, minute, second, microsecond 5 #<class 'datetime.time'> 6 print(datetime.datetime) #表示日期時間 7 #<class 'datetime.datetime'> 8 print(datetime.timedelta) #表示時間間隔,即兩個時間點之間的長度 9 #<class 'datetime.timedelta'> 10 print(datetime.datetime.now()) 11 #2016-08-25 14:21:07.722285 12 print(datetime.datetime.now() - datetime.timedelta(days=5)) 13 #2016-08-20 14:21:28.275460
1 import time 2 3 str = '2017-03-26 3:12' 4 str2 = '2017-05-26 13:12' 5 date1 = time.strptime(str, '%Y-%m-%d %H:%M') 6 date2 = time.strptime(str2, '%Y-%m-%d %H:%M') 7 if float(time.time()) >= float(time.mktime(date1)) and float(time.time()) <= float(time.mktime(date2)): 8 print 'cccccccc' 9 10 11 import datetime 12 13 str = '2017-03-26 3:12' 14 str2 = '2017-05-26 13:12' 15 date1 = datetime.datetime.strptime(str,'%Y-%m-%d %H:%M') 16 date2 = datetime.datetime.strptime(str2,'%Y-%m-%d %H:%M') 17 datenow = datetime.datetime.now() 18 if datenow <date1: 19 print 'dddddd' 20 21 時間比較
(2)random模塊:生成隨機數(驗證碼)
1 #random隨機數模塊 2 import random 3 print(random.random()) #生成0到1的隨機數 4 #0.7308387398872364 5 print(random.randint(1,3)) #生成1-3隨機數 6 #3 7 print(random.randrange(1,3)) #生成1-2隨機數,不包含3 8 #2 9 print(random.choice("hello")) #隨機選取字符串 10 #e 11 print(random.sample("hello",2)) #隨機選取特定的字符 12 #['l', 'h'] 13 items = [1,2,3,4,5,6,7] 14 random.shuffle(items) 15 print(items) 16 #[2, 3, 1, 6, 4, 7, 5]
1 import random 2 checkcode = '' 3 for i in range(4): 4 current = random.randrange(0,4) 5 if current != i: 6 temp = chr(random.randint(65,90)) 7 else: 8 temp = random.randint(0,9) 9 checkcode += str(temp) 10 print(checkcode) 11 #51T6
(3)os模塊:用於提供系統級別的操做(好比目錄、路徑等的操做)
1 import os 2 os.getcwd() #獲取當前工做目錄,即當前python腳本工做的目錄路徑 3 os.chdir("dirname") #改變當前腳本工做目錄;至關於shell下cd 4 os.curdir #返回當前目錄: ('.') 5 os.pardir #獲取當前目錄的父目錄字符串名:('..') 6 os.makedirs('dirname1/dirname2') #可生成多層遞歸目錄 7 os.removedirs('dirname1') # 若目錄爲空,則刪除,並遞歸到上一級目錄,如若也爲空,則刪除,依此類推 8 os.mkdir('dirname') # 生成單級目錄;至關於shell中mkdir dirname 9 os.rmdir('dirname') #刪除單級空目錄,若目錄不爲空則沒法刪除,報錯;至關於shell中rmdir dirname 10 os.listdir('dirname') #列出指定目錄下的全部文件和子目錄,包括隱藏文件,並以列表方式打印 11 os.remove() # 刪除一個文件 12 os.rename("oldname","newname") # 重命名文件/目錄 13 os.stat('path/filename') # 獲取文件/目錄信息 14 os.sep #輸出操做系統特定的路徑分隔符,win下爲"\\",Linux下爲"/" 15 os.linesep #輸出當前平臺使用的行終止符,win下爲"\t\n",Linux下爲"\n" 16 os.pathsep #輸出用於分割文件路徑的字符串 17 os.name #輸出字符串指示當前使用平臺。win->'nt'; Linux->'posix' 18 os.system("bash command") #運行shell命令,直接顯示 19 os.environ #獲取系統環境變量 20 os.path.abspath(path) #返回path規範化的絕對路徑 21 os.path.split(path) #將path分割成目錄和文件名二元組返回 22 os.path.dirname(path) # 返回path的目錄。其實就是os.path.split(path)的第一個元素 23 os.path.basename(path) # 返回path最後的文件名。如何path以/或\結尾,那麼就會返回空值。即os.path.split(path)的第二個元素 24 os.path.exists(path) #若是path存在,返回True;若是path不存在,返回False 25 os.path.isabs(path) #若是path是絕對路徑,返回True 26 os.path.isfile(path) #若是path是一個存在的文件,返回True。不然返回False 27 os.path.isdir(path) #若是path是一個存在的目錄,則返回True。不然返回False 28 os.path.join(path1[, path2[, ...]]) # 將多個路徑組合後返回,第一個絕對路徑以前的參數將被忽略 29 os.path.getatime(path) #返回path所指向的文件或者目錄的最後存取時間 30 os.path.getmtime(path) #返回path所指向的文件或者目錄的最後修改時間
(4)sys模塊:用於提供對解釋器相關的操做(好比退出程序、版本信息等)
1 import sys 2 sys.argv #命令行參數List,第一個元素是程序自己路徑 3 sys.exit(n) #退出程序,正常退出時exit(0) 4 sys.version # 獲取Python解釋程序的版本信息 5 sys.maxint #最大的Int值 6 sys.path #返回模塊的搜索路徑,初始化時使用PYTHONPATH環境變量的值 7 sys.platform #返回操做系統平臺名稱 8 sys.stdout.write('please:') 9 val = sys.stdin.readline()[:-1]
(5)shutil模塊:高級的(文件、文件夾、壓縮包)處理模塊 (好比文件的拷貝、壓縮等)
① shutil.copyfileobj 將文件內容拷貝到另外一個文件中,能夠部份內容
1 def copyfileobj(fsrc, fdst, length=16*1024): 2 """copy data from file-like object fsrc to file-like object fdst""" 3 while 1: 4 buf = fsrc.read(length) 5 if not buf: 6 break 7 fdst.write(buf)
1 import shutil 2 f1 = open("fsrc",encoding="utf-8") 3 f2 = open("fdst",encoding="utf-8") 4 shutil.copyfile(f1,f2) 5 #把文件f1裏的內容拷貝到f2當中
② shutil.copyfile 文件拷貝
1 def copyfile(src, dst): 2 """Copy data from src to dst""" 3 if _samefile(src, dst): 4 raise Error("`%s` and `%s` are the same file" % (src, dst)) 5 for fn in [src, dst]: 6 try: 7 st = os.stat(fn) 8 except OSError: 9 # File most likely does not exist 10 pass 11 else: 12 # XXX What about other special files? (sockets, devices...) 13 if stat.S_ISFIFO(st.st_mode): 14 raise SpecialFileError("`%s` is a named pipe" % fn) 15 with open(src, 'rb') as fsrc: 16 with open(dst, 'wb') as fdst: 17 copyfileobj(fsrc, fdst)
1 import shutil 2 shutil.copyfile("f1","f2") 3 #把文件f1裏的內容拷貝到f2當中
③ shutil.copymode(src, dst) 僅拷貝權限。內容、組、用戶均不變
1 def copymode(src, dst): 2 """Copy mode bits from src to dst""" 3 if hasattr(os, 'chmod'): 4 st = os.stat(src) 5 mode = stat.S_IMODE(st.st_mode) 6 os.chmod(dst, mode)
④ shutil.copystat(src, dst) 拷貝狀態的信息,包括:mode bits, atime, mtime, flags
1 def copystat(src, dst): 2 """Copy all stat info (mode bits, atime, mtime, flags) from src to dst""" 3 st = os.stat(src) 4 mode = stat.S_IMODE(st.st_mode) 5 if hasattr(os, 'utime'): 6 os.utime(dst, (st.st_atime, st.st_mtime)) 7 if hasattr(os, 'chmod'): 8 os.chmod(dst, mode) 9 if hasattr(os, 'chflags') and hasattr(st, 'st_flags'): 10 try: 11 os.chflags(dst, st.st_flags) 12 except OSError, why: 13 for err in 'EOPNOTSUPP', 'ENOTSUP': 14 if hasattr(errno, err) and why.errno == getattr(errno, err): 15 break 16 else: 17 raise
⑤ shutil.copy(src, dst) 拷貝文件和權限
1 def copy(src, dst): 2 """Copy data and mode bits ("cp src dst"). 3 4 The destination may be a directory. 5 6 """ 7 if os.path.isdir(dst): 8 dst = os.path.join(dst, os.path.basename(src)) 9 copyfile(src, dst) 10 copymode(src, dst)
⑥ shutil.copy2(src, dst) 拷貝文件和狀態信息
1 def copy2(src, dst): 2 """Copy data and all stat info ("cp -p src dst"). 3 4 The destination may be a directory. 5 6 """ 7 if os.path.isdir(dst): 8 dst = os.path.join(dst, os.path.basename(src)) 9 copyfile(src, dst) 10 copystat(src, dst)
⑦ shutil.copytree(src, dst, symlinks=False, ignore=None) 遞歸的去拷貝文件 拷貝多層目錄
1 def ignore_patterns(*patterns): 2 """Function that can be used as copytree() ignore parameter. 3 4 Patterns is a sequence of glob-style patterns 5 that are used to exclude files""" 6 def _ignore_patterns(path, names): 7 ignored_names = [] 8 for pattern in patterns: 9 ignored_names.extend(fnmatch.filter(names, pattern)) 10 return set(ignored_names) 11 return _ignore_patterns 12 def copytree(src, dst, symlinks=False, ignore=None): 13 """Recursively copy a directory tree using copy2(). 14 15 The destination directory must not already exist. 16 If exception(s) occur, an Error is raised with a list of reasons. 17 18 If the optional symlinks flag is true, symbolic links in the 19 source tree result in symbolic links in the destination tree; if 20 it is false, the contents of the files pointed to by symbolic 21 links are copied. 22 23 The optional ignore argument is a callable. If given, it 24 is called with the `src` parameter, which is the directory 25 being visited by copytree(), and `names` which is the list of 26 `src` contents, as returned by os.listdir(): 27 28 callable(src, names) -> ignored_names 29 30 Since copytree() is called recursively, the callable will be 31 called once for each directory that is copied. It returns a 32 list of names relative to the `src` directory that should 33 not be copied. 34 35 XXX Consider this example code rather than the ultimate tool. 36 37 """ 38 names = os.listdir(src) 39 if ignore is not None: 40 ignored_names = ignore(src, names) 41 else: 42 ignored_names = set() 43 44 os.makedirs(dst) 45 errors = [] 46 for name in names: 47 if name in ignored_names: 48 continue 49 srcname = os.path.join(src, name) 50 dstname = os.path.join(dst, name) 51 try: 52 if symlinks and os.path.islink(srcname): 53 linkto = os.readlink(srcname) 54 os.symlink(linkto, dstname) 55 elif os.path.isdir(srcname): 56 copytree(srcname, dstname, symlinks, ignore) 57 else: 58 # Will raise a SpecialFileError for unsupported file types copy2(srcname, dstname) 59 # catch the Error from the recursive copytree so that we can 60 # continue with other files 61 except Error, err: 62 errors.extend(err.args[0]) 63 except EnvironmentError, why: 64 errors.append((srcname, dstname, str(why))) 65 try: 66 copystat(src, dst) 67 except OSError, why: 68 if WindowsError is not None and isinstance(why, WindowsError): 69 # Copying file access times may fail on Windows 70 pass 71 else: 72 errors.append((src, dst, str(why))) 73 if errors: 74 raise Error, errors
⑧ shutil.rmtree(path[, ignore_errors[, onerror]]) 遞歸的去刪除文件
1 def rmtree(path, ignore_errors=False, onerror=None): 2 """Recursively delete a directory tree. 3 4 If ignore_errors is set, errors are ignored; otherwise, if onerror 5 is set, it is called to handle the error with arguments (func, 6 path, exc_info) where func is os.listdir, os.remove, or os.rmdir; 7 path is the argument to that function that caused it to fail; and 8 exc_info is a tuple returned by sys.exc_info(). If ignore_errors 9 is false and onerror is None, an exception is raised. 10 11 """ 12 if ignore_errors: 13 def onerror(*args): 14 pass 15 elif onerror is None: 16 def onerror(*args): 17 raise 18 try: 19 if os.path.islink(path): 20 # symlinks to directories are forbidden, see bug #1669 21 raise OSError("Cannot call rmtree on a symbolic link") 22 except OSError: 23 onerror(os.path.islink, path, sys.exc_info()) 24 # can't continue even if onerror hook returns 25 return 26 names = [] 27 try: 28 names = os.listdir(path) 29 except os.error, err: 30 onerror(os.listdir, path, sys.exc_info()) 31 for name in names: 32 fullname = os.path.join(path, name) 33 try: 34 mode = os.lstat(fullname).st_mode 35 except os.error: 36 mode = 0 37 if stat.S_ISDIR(mode): 38 rmtree(fullname, ignore_errors, onerror) 39 else: 40 try: 41 os.remove(fullname) 42 except os.error, err: 43 onerror(os.remove, fullname, sys.exc_info()) 44 try: 45 os.rmdir(path) 46 except os.error: 47 onerror(os.rmdir, path, sys.exc_info())
⑨ shutil.move(src, dst) 遞歸的去移動文件
1 def move(src, dst): 2 """Recursively move a file or directory to another location. This is 3 similar to the Unix "mv" command. 4 5 If the destination is a directory or a symlink to a directory, the source 6 is moved inside the directory. The destination path must not already 7 exist. 8 9 If the destination already exists but is not a directory, it may be 10 overwritten depending on os.rename() semantics. 11 12 If the destination is on our current filesystem, then rename() is used. 13 Otherwise, src is copied to the destination and then removed. 14 A lot more could be done here... A look at a mv.c shows a lot of 15 the issues this implementation glosses over. 16 17 """ 18 real_dst = dst 19 if os.path.isdir(dst): 20 if _samefile(src, dst): 21 # We might be on a case insensitive filesystem, 22 # perform the rename anyway. os.rename(src, dst) 23 return 24 25 real_dst = os.path.join(dst, _basename(src)) 26 if os.path.exists(real_dst): 27 raise Error, "Destination path '%s' already exists" % real_dst 28 try: 29 os.rename(src, real_dst) 30 except OSError: 31 if os.path.isdir(src): 32 if _destinsrc(src, dst): 33 raise Error, "Cannot move a directory '%s' into itself '%s'." % (src, dst) 34 copytree(src, real_dst, symlinks=True) 35 rmtree(src) 36 else: 37 copy2(src, real_dst) 38 os.unlink(src)
⑩ shutil.make_archive(base_name, format,...) 建立壓縮包並返回文件路徑,例如:zip、tar
base_name: 壓縮包的文件名,也能夠是壓縮包的路徑。只是文件名時,則保存至當前目錄,不然保存至指定路徑,
如:www =>保存至當前路徑
如:/Users/wupeiqi/www =>保存至/Users/wupeiqi/
format: 壓縮包種類,「zip」, 「tar」, 「bztar」,「gztar」
root_dir: 要壓縮的文件夾路徑(默認當前目錄)
owner: 用戶,默認當前用戶
group: 組,默認當前組
logger: 用於記錄日誌,一般是logging.Logger對象
1 def make_archive(base_name, format, root_dir=None, base_dir=None, verbose=0, 2 dry_run=0, owner=None, group=None, logger=None): 3 """Create an archive file (eg. zip or tar). 4 5 'base_name' is the name of the file to create, minus any format-specific 6 extension; 'format' is the archive format: one of "zip", "tar", "bztar" 7 or "gztar". 8 9 'root_dir' is a directory that will be the root directory of the 10 archive; ie. we typically chdir into 'root_dir' before creating the 11 archive. 'base_dir' is the directory where we start archiving from; 12 ie. 'base_dir' will be the common prefix of all files and 13 directories in the archive. 'root_dir' and 'base_dir' both default 14 to the current directory. Returns the name of the archive file. 15 16 'owner' and 'group' are used when creating a tar archive. By default, 17 uses the current owner and group. 18 """ 19 save_cwd = os.getcwd() 20 if root_dir is not None: 21 if logger is not None: 22 logger.debug("changing into '%s'", root_dir) 23 base_name = os.path.abspath(base_name) 24 if not dry_run: 25 os.chdir(root_dir) 26 27 if base_dir is None: 28 base_dir = os.curdir 29 30 kwargs = {'dry_run': dry_run, 'logger': logger} 31 32 try: 33 format_info = _ARCHIVE_FORMATS[format] 34 except KeyError: 35 raise ValueError, "unknown archive format '%s'" % format 36 37 func = format_info[0] 38 for arg, val in format_info[1]: 39 kwargs[arg] = val 40 41 if format != 'zip': 42 kwargs['owner'] = owner 43 kwargs['group'] = group 44 45 try: 46 filename = func(base_name, base_dir, **kwargs) 47 finally: 48 if root_dir is not None: 49 if logger is not None: 50 logger.debug("changing back to '%s'", save_cwd) 51 os.chdir(save_cwd) 52 53 return filename 54 55 源碼
shutil 對壓縮包的處理是調用 ZipFile 和 TarFile 兩個模塊來進行的,詳細:
1 import zipfile 2 3 # 壓縮 4 z = zipfile.ZipFile('laxi.zip', 'w') 5 z.write('a.log') 6 z.write('data.data') 7 z.close() 8 9 # 解壓 10 z = zipfile.ZipFile('laxi.zip', 'r') 11 z.extractall() 12 z.close() 13 14 zipfile 壓縮解壓 15 16 zipfile 壓縮解壓
1 import tarfile 2 3 # 壓縮 4 tar = tarfile.open('your.tar','w') 5 tar.add('/Users/wupeiqi/PycharmProjects/bbs2.zip', arcname='bbs2.zip') 6 tar.add('/Users/wupeiqi/PycharmProjects/cmdb.zip', arcname='cmdb.zip') 7 tar.close() 8 9 # 解壓 10 tar = tarfile.open('your.tar','r') 11 tar.extractall() # 可設置解壓地址 12 tar.close() 13 14 tarfile 壓縮解壓 15 16 tarfile 壓縮解壓
1 class ZipFile(object): 2 """ Class with methods to open, read, write, close, list zip files. 3 4 z = ZipFile(file, mode="r", compression=ZIP_STORED, allowZip64=False) 5 6 file: Either the path to the file, or a file-like object. 7 If it is a path, the file will be opened and closed by ZipFile. 8 mode: The mode can be either read "r", write "w" or append "a". 9 compression: ZIP_STORED (no compression) or ZIP_DEFLATED (requires zlib). 10 allowZip64: if True ZipFile will create files with ZIP64 extensions when 11 needed, otherwise it will raise an exception when this would 12 be necessary. 13 14 """ 15 16 fp = None # Set here since __del__ checks it 17 18 def __init__(self, file, mode="r", compression=ZIP_STORED, allowZip64=False): 19 """Open the ZIP file with mode read "r", write "w" or append "a".""" 20 if mode not in ("r", "w", "a"): 21 raise RuntimeError('ZipFile() requires mode "r", "w", or "a"') 22 23 if compression == ZIP_STORED: 24 pass 25 elif compression == ZIP_DEFLATED: 26 if not zlib: 27 raise RuntimeError,\ 28 "Compression requires the (missing) zlib module" 29 else: 30 raise RuntimeError, "That compression method is not supported" 31 32 self._allowZip64 = allowZip64 33 self._didModify = False 34 self.debug = 0 # Level of printing: 0 through 3 35 self.NameToInfo = {} # Find file info given name 36 self.filelist = [] # List of ZipInfo instances for archive 37 self.compression = compression # Method of compression 38 self.mode = key = mode.replace('b', '')[0] 39 self.pwd = None 40 self._comment = '' 41 42 # Check if we were passed a file-like object 43 if isinstance(file, basestring): 44 self._filePassed = 0 45 self.filename = file 46 modeDict = {'r' : 'rb', 'w': 'wb', 'a' : 'r+b'} 47 try: 48 self.fp = open(file, modeDict[mode]) 49 except IOError: 50 if mode == 'a': 51 mode = key = 'w' 52 self.fp = open(file, modeDict[mode]) 53 else: 54 raise 55 else: 56 self._filePassed = 1 57 self.fp = file 58 self.filename = getattr(file, 'name', None) 59 60 try: 61 if key == 'r': 62 self._RealGetContents() 63 elif key == 'w': 64 # set the modified flag so central directory gets written 65 # even if no files are added to the archive 66 self._didModify = True 67 elif key == 'a': 68 try: 69 # See if file is a zip file 70 self._RealGetContents() 71 # seek to start of directory and overwrite 72 self.fp.seek(self.start_dir, 0) 73 except BadZipfile: 74 # file is not a zip file, just append 75 self.fp.seek(0, 2) 76 77 # set the modified flag so central directory gets written 78 # even if no files are added to the archive 79 self._didModify = True 80 else: 81 raise RuntimeError('Mode must be "r", "w" or "a"') 82 except: 83 fp = self.fp 84 self.fp = None 85 if not self._filePassed: 86 fp.close() 87 raise 88 89 def __enter__(self): 90 return self 91 92 def __exit__(self, type, value, traceback): 93 self.close() 94 95 def _RealGetContents(self): 96 """Read in the table of contents for the ZIP file.""" 97 fp = self.fp 98 try: 99 endrec = _EndRecData(fp) 100 except IOError: 101 raise BadZipfile("File is not a zip file") 102 if not endrec: 103 raise BadZipfile, "File is not a zip file" 104 if self.debug > 1: 105 print endrec 106 size_cd = endrec[_ECD_SIZE] # bytes in central directory 107 offset_cd = endrec[_ECD_OFFSET] # offset of central directory 108 self._comment = endrec[_ECD_COMMENT] # archive comment 109 110 # "concat" is zero, unless zip was concatenated to another file 111 concat = endrec[_ECD_LOCATION] - size_cd - offset_cd 112 if endrec[_ECD_SIGNATURE] == stringEndArchive64: 113 # If Zip64 extension structures are present, account for them 114 concat -= (sizeEndCentDir64 + sizeEndCentDir64Locator) 115 116 if self.debug > 2: 117 inferred = concat + offset_cd 118 print "given, inferred, offset", offset_cd, inferred, concat 119 # self.start_dir: Position of start of central directory 120 self.start_dir = offset_cd + concat 121 fp.seek(self.start_dir, 0) 122 data = fp.read(size_cd) 123 fp = cStringIO.StringIO(data) 124 total = 0 125 while total < size_cd: 126 centdir = fp.read(sizeCentralDir) 127 if len(centdir) != sizeCentralDir: 128 raise BadZipfile("Truncated central directory") 129 centdir = struct.unpack(structCentralDir, centdir) 130 if centdir[_CD_SIGNATURE] != stringCentralDir: 131 raise BadZipfile("Bad magic number for central directory") 132 if self.debug > 2: 133 print centdir 134 filename = fp.read(centdir[_CD_FILENAME_LENGTH]) 135 # Create ZipInfo instance to store file information 136 x = ZipInfo(filename) 137 x.extra = fp.read(centdir[_CD_EXTRA_FIELD_LENGTH]) 138 x.comment = fp.read(centdir[_CD_COMMENT_LENGTH]) 139 x.header_offset = centdir[_CD_LOCAL_HEADER_OFFSET] 140 (x.create_version, x.create_system, x.extract_version, x.reserved, 141 x.flag_bits, x.compress_type, t, d, 142 x.CRC, x.compress_size, x.file_size) = centdir[1:12] 143 x.volume, x.internal_attr, x.external_attr = centdir[15:18] 144 # Convert date/time code to (year, month, day, hour, min, sec) 145 x._raw_time = t 146 x.date_time = ( (d>>9)+1980, (d>>5)&0xF, d&0x1F, 147 t>>11, (t>>5)&0x3F, (t&0x1F) * 2 ) 148 149 x._decodeExtra() 150 x.header_offset = x.header_offset + concat 151 x.filename = x._decodeFilename() 152 self.filelist.append(x) 153 self.NameToInfo[x.filename] = x 154 155 # update total bytes read from central directory 156 total = (total + sizeCentralDir + centdir[_CD_FILENAME_LENGTH] 157 + centdir[_CD_EXTRA_FIELD_LENGTH] 158 + centdir[_CD_COMMENT_LENGTH]) 159 160 if self.debug > 2: 161 print "total", total 162 163 164 def namelist(self): 165 """Return a list of file names in the archive.""" 166 l = [] 167 for data in self.filelist: 168 l.append(data.filename) 169 return l 170 171 def infolist(self): 172 """Return a list of class ZipInfo instances for files in the 173 archive.""" 174 return self.filelist 175 176 def printdir(self): 177 """Print a table of contents for the zip file.""" 178 print "%-46s %19s %12s" % ("File Name", "Modified ", "Size") 179 for zinfo in self.filelist: 180 date = "%d-%02d-%02d %02d:%02d:%02d" % zinfo.date_time[:6] 181 print "%-46s %s %12d" % (zinfo.filename, date, zinfo.file_size) 182 183 def testzip(self): 184 """Read all the files and check the CRC.""" 185 chunk_size = 2 ** 20 186 for zinfo in self.filelist: 187 try: 188 # Read by chunks, to avoid an OverflowError or a 189 # MemoryError with very large embedded files. 190 with self.open(zinfo.filename, "r") as f: 191 while f.read(chunk_size): # Check CRC-32 192 pass 193 except BadZipfile: 194 return zinfo.filename 195 196 def getinfo(self, name): 197 """Return the instance of ZipInfo given 'name'.""" 198 info = self.NameToInfo.get(name) 199 if info is None: 200 raise KeyError( 201 'There is no item named %r in the archive' % name) 202 203 return info 204 205 def setpassword(self, pwd): 206 """Set default password for encrypted files.""" 207 self.pwd = pwd 208 209 @property 210 def comment(self): 211 """The comment text associated with the ZIP file.""" 212 return self._comment 213 214 @comment.setter 215 def comment(self, comment): 216 # check for valid comment length 217 if len(comment) > ZIP_MAX_COMMENT: 218 import warnings 219 warnings.warn('Archive comment is too long; truncating to %d bytes' 220 % ZIP_MAX_COMMENT, stacklevel=2) 221 comment = comment[:ZIP_MAX_COMMENT] 222 self._comment = comment 223 self._didModify = True 224 225 def read(self, name, pwd=None): 226 """Return file bytes (as a string) for name.""" 227 return self.open(name, "r", pwd).read() 228 229 def open(self, name, mode="r", pwd=None): 230 """Return file-like object for 'name'.""" 231 if mode not in ("r", "U", "rU"): 232 raise RuntimeError, 'open() requires mode "r", "U", or "rU"' 233 if not self.fp: 234 raise RuntimeError, \ 235 "Attempt to read ZIP archive that was already closed" 236 237 # Only open a new file for instances where we were not 238 # given a file object in the constructor 239 if self._filePassed: 240 zef_file = self.fp 241 should_close = False 242 else: 243 zef_file = open(self.filename, 'rb') 244 should_close = True 245 246 try: 247 # Make sure we have an info object 248 if isinstance(name, ZipInfo): 249 # 'name' is already an info object 250 zinfo = name 251 else: 252 # Get info object for name 253 zinfo = self.getinfo(name) 254 255 zef_file.seek(zinfo.header_offset, 0) 256 257 # Skip the file header: 258 fheader = zef_file.read(sizeFileHeader) 259 if len(fheader) != sizeFileHeader: 260 raise BadZipfile("Truncated file header") 261 fheader = struct.unpack(structFileHeader, fheader) 262 if fheader[_FH_SIGNATURE] != stringFileHeader: 263 raise BadZipfile("Bad magic number for file header") 264 265 fname = zef_file.read(fheader[_FH_FILENAME_LENGTH]) 266 if fheader[_FH_EXTRA_FIELD_LENGTH]: 267 zef_file.read(fheader[_FH_EXTRA_FIELD_LENGTH]) 268 269 if fname != zinfo.orig_filename: 270 raise BadZipfile, \ 271 'File name in directory "%s" and header "%s" differ.' % ( 272 zinfo.orig_filename, fname) 273 274 # check for encrypted flag & handle password 275 is_encrypted = zinfo.flag_bits & 0x1 276 zd = None 277 if is_encrypted: 278 if not pwd: 279 pwd = self.pwd 280 if not pwd: 281 raise RuntimeError, "File %s is encrypted, " \ 282 "password required for extraction" % name 283 284 zd = _ZipDecrypter(pwd) 285 # The first 12 bytes in the cypher stream is an encryption header 286 # used to strengthen the algorithm. The first 11 bytes are 287 # completely random, while the 12th contains the MSB of the CRC, 288 # or the MSB of the file time depending on the header type 289 # and is used to check the correctness of the password. 290 bytes = zef_file.read(12) 291 h = map(zd, bytes[0:12]) 292 if zinfo.flag_bits & 0x8: 293 # compare against the file type from extended local headers 294 check_byte = (zinfo._raw_time >> 8) & 0xff 295 else: 296 # compare against the CRC otherwise 297 check_byte = (zinfo.CRC >> 24) & 0xff 298 if ord(h[11]) != check_byte: 299 raise RuntimeError("Bad password for file", name) 300 301 return ZipExtFile(zef_file, mode, zinfo, zd, 302 close_fileobj=should_close) 303 except: 304 if should_close: 305 zef_file.close() 306 raise 307 308 def extract(self, member, path=None, pwd=None): 309 """Extract a member from the archive to the current working directory, 310 using its full name. Its file information is extracted as accurately 311 as possible. `member' may be a filename or a ZipInfo object. You can 312 specify a different directory using `path'. 313 """ 314 if not isinstance(member, ZipInfo): 315 member = self.getinfo(member) 316 317 if path is None: 318 path = os.getcwd() 319 320 return self._extract_member(member, path, pwd) 321 322 def extractall(self, path=None, members=None, pwd=None): 323 """Extract all members from the archive to the current working 324 directory. `path' specifies a different directory to extract to. 325 `members' is optional and must be a subset of the list returned 326 by namelist(). 327 """ 328 if members is None: 329 members = self.namelist() 330 331 for zipinfo in members: 332 self.extract(zipinfo, path, pwd) 333 334 def _extract_member(self, member, targetpath, pwd): 335 """Extract the ZipInfo object 'member' to a physical 336 file on the path targetpath. 337 """ 338 # build the destination pathname, replacing 339 # forward slashes to platform specific separators. 340 arcname = member.filename.replace('/', os.path.sep) 341 342 if os.path.altsep: 343 arcname = arcname.replace(os.path.altsep, os.path.sep) 344 # interpret absolute pathname as relative, remove drive letter or 345 # UNC path, redundant separators, "." and ".." components. 346 arcname = os.path.splitdrive(arcname)[1] 347 arcname = os.path.sep.join(x for x in arcname.split(os.path.sep) 348 if x not in ('', os.path.curdir, os.path.pardir)) 349 if os.path.sep == '\\': 350 # filter illegal characters on Windows 351 illegal = ':<>|"?*' 352 if isinstance(arcname, unicode): 353 table = {ord(c): ord('_') for c in illegal} 354 else: 355 table = string.maketrans(illegal, '_' * len(illegal)) 356 arcname = arcname.translate(table) 357 # remove trailing dots 358 arcname = (x.rstrip('.') for x in arcname.split(os.path.sep)) 359 arcname = os.path.sep.join(x for x in arcname if x) 360 361 targetpath = os.path.join(targetpath, arcname) 362 targetpath = os.path.normpath(targetpath) 363 364 # Create all upper directories if necessary. 365 upperdirs = os.path.dirname(targetpath) 366 if upperdirs and not os.path.exists(upperdirs): 367 os.makedirs(upperdirs) 368 369 if member.filename[-1] == '/': 370 if not os.path.isdir(targetpath): 371 os.mkdir(targetpath) 372 return targetpath 373 374 with self.open(member, pwd=pwd) as source, \ 375 file(targetpath, "wb") as target: 376 shutil.copyfileobj(source, target) 377 378 return targetpath 379 380 def _writecheck(self, zinfo): 381 """Check for errors before writing a file to the archive.""" 382 if zinfo.filename in self.NameToInfo: 383 import warnings 384 warnings.warn('Duplicate name: %r' % zinfo.filename, stacklevel=3) 385 if self.mode not in ("w", "a"): 386 raise RuntimeError, 'write() requires mode "w" or "a"' 387 if not self.fp: 388 raise RuntimeError, \ 389 "Attempt to write ZIP archive that was already closed" 390 if zinfo.compress_type == ZIP_DEFLATED and not zlib: 391 raise RuntimeError, \ 392 "Compression requires the (missing) zlib module" 393 if zinfo.compress_type not in (ZIP_STORED, ZIP_DEFLATED): 394 raise RuntimeError, \ 395 "That compression method is not supported" 396 if not self._allowZip64: 397 requires_zip64 = None 398 if len(self.filelist) >= ZIP_FILECOUNT_LIMIT: 399 requires_zip64 = "Files count" 400 elif zinfo.file_size > ZIP64_LIMIT: 401 requires_zip64 = "Filesize" 402 elif zinfo.header_offset > ZIP64_LIMIT: 403 requires_zip64 = "Zipfile size" 404 if requires_zip64: 405 raise LargeZipFile(requires_zip64 + 406 " would require ZIP64 extensions") 407 408 def write(self, filename, arcname=None, compress_type=None): 409 """Put the bytes from filename into the archive under the name 410 arcname.""" 411 if not self.fp: 412 raise RuntimeError( 413 "Attempt to write to ZIP archive that was already closed") 414 415 st = os.stat(filename) 416 isdir = stat.S_ISDIR(st.st_mode) 417 mtime = time.localtime(st.st_mtime) 418 date_time = mtime[0:6] 419 # Create ZipInfo instance to store file information 420 if arcname is None: 421 arcname = filename 422 arcname = os.path.normpath(os.path.splitdrive(arcname)[1]) 423 while arcname[0] in (os.sep, os.altsep): 424 arcname = arcname[1:] 425 if isdir: 426 arcname += '/' 427 zinfo = ZipInfo(arcname, date_time) 428 zinfo.external_attr = (st[0] & 0xFFFF) << 16L # Unix attributes 429 if compress_type is None: 430 zinfo.compress_type = self.compression 431 else: 432 zinfo.compress_type = compress_type 433 434 zinfo.file_size = st.st_size 435 zinfo.flag_bits = 0x00 436 zinfo.header_offset = self.fp.tell() # Start of header bytes 437 438 self._writecheck(zinfo) 439 self._didModify = True 440 441 if isdir: 442 zinfo.file_size = 0 443 zinfo.compress_size = 0 444 zinfo.CRC = 0 445 zinfo.external_attr |= 0x10 # MS-DOS directory flag 446 self.filelist.append(zinfo) 447 self.NameToInfo[zinfo.filename] = zinfo 448 self.fp.write(zinfo.FileHeader(False)) 449 return 450 451 with open(filename, "rb") as fp: 452 # Must overwrite CRC and sizes with correct data later 453 zinfo.CRC = CRC = 0 454 zinfo.compress_size = compress_size = 0 455 # Compressed size can be larger than uncompressed size 456 zip64 = self._allowZip64 and \ 457 zinfo.file_size * 1.05 > ZIP64_LIMIT 458 self.fp.write(zinfo.FileHeader(zip64)) 459 if zinfo.compress_type == ZIP_DEFLATED: 460 cmpr = zlib.compressobj(zlib.Z_DEFAULT_COMPRESSION, 461 zlib.DEFLATED, -15) 462 else: 463 cmpr = None 464 file_size = 0 465 while 1: 466 buf = fp.read(1024 * 8) 467 if not buf: 468 break 469 file_size = file_size + len(buf) 470 CRC = crc32(buf, CRC) & 0xffffffff 471 if cmpr: 472 buf = cmpr.compress(buf) 473 compress_size = compress_size + len(buf) 474 self.fp.write(buf) 475 if cmpr: 476 buf = cmpr.flush() 477 compress_size = compress_size + len(buf) 478 self.fp.write(buf) 479 zinfo.compress_size = compress_size 480 else: 481 zinfo.compress_size = file_size 482 zinfo.CRC = CRC 483 zinfo.file_size = file_size 484 if not zip64 and self._allowZip64: 485 if file_size > ZIP64_LIMIT: 486 raise RuntimeError('File size has increased during compressing') 487 if compress_size > ZIP64_LIMIT: 488 raise RuntimeError('Compressed size larger than uncompressed size') 489 # Seek backwards and write file header (which will now include 490 # correct CRC and file sizes) 491 position = self.fp.tell() # Preserve current position in file 492 self.fp.seek(zinfo.header_offset, 0) 493 self.fp.write(zinfo.FileHeader(zip64)) 494 self.fp.seek(position, 0) 495 self.filelist.append(zinfo) 496 self.NameToInfo[zinfo.filename] = zinfo 497 498 def writestr(self, zinfo_or_arcname, bytes, compress_type=None): 499 """Write a file into the archive. The contents is the string 500 'bytes'. 'zinfo_or_arcname' is either a ZipInfo instance or 501 the name of the file in the archive.""" 502 if not isinstance(zinfo_or_arcname, ZipInfo): 503 zinfo = ZipInfo(filename=zinfo_or_arcname, 504 date_time=time.localtime(time.time())[:6]) 505 506 zinfo.compress_type = self.compression 507 if zinfo.filename[-1] == '/': 508 zinfo.external_attr = 0o40775 << 16 # drwxrwxr-x 509 zinfo.external_attr |= 0x10 # MS-DOS directory flag 510 else: 511 zinfo.external_attr = 0o600 << 16 # ?rw------- 512 else: 513 zinfo = zinfo_or_arcname 514 515 if not self.fp: 516 raise RuntimeError( 517 "Attempt to write to ZIP archive that was already closed") 518 519 if compress_type is not None: 520 zinfo.compress_type = compress_type 521 522 zinfo.file_size = len(bytes) # Uncompressed size 523 zinfo.header_offset = self.fp.tell() # Start of header bytes 524 self._writecheck(zinfo) 525 self._didModify = True 526 zinfo.CRC = crc32(bytes) & 0xffffffff # CRC-32 checksum 527 if zinfo.compress_type == ZIP_DEFLATED: 528 co = zlib.compressobj(zlib.Z_DEFAULT_COMPRESSION, 529 zlib.DEFLATED, -15) 530 bytes = co.compress(bytes) + co.flush() 531 zinfo.compress_size = len(bytes) # Compressed size 532 else: 533 zinfo.compress_size = zinfo.file_size 534 zip64 = zinfo.file_size > ZIP64_LIMIT or \ 535 zinfo.compress_size > ZIP64_LIMIT 536 if zip64 and not self._allowZip64: 537 raise LargeZipFile("Filesize would require ZIP64 extensions") 538 self.fp.write(zinfo.FileHeader(zip64)) 539 self.fp.write(bytes) 540 if zinfo.flag_bits & 0x08: 541 # Write CRC and file sizes after the file data 542 fmt = '<LQQ' if zip64 else '<LLL' 543 self.fp.write(struct.pack(fmt, zinfo.CRC, zinfo.compress_size, 544 zinfo.file_size)) 545 self.fp.flush() 546 self.filelist.append(zinfo) 547 self.NameToInfo[zinfo.filename] = zinfo 548 549 def __del__(self): 550 """Call the "close()" method in case the user forgot.""" 551 self.close() 552 553 def close(self): 554 """Close the file, and for mode "w" and "a" write the ending 555 records.""" 556 if self.fp is None: 557 return 558 559 try: 560 if self.mode in ("w", "a") and self._didModify: # write ending records 561 pos1 = self.fp.tell() 562 for zinfo in self.filelist: # write central directory 563 dt = zinfo.date_time 564 dosdate = (dt[0] - 1980) << 9 | dt[1] << 5 | dt[2] 565 dostime = dt[3] << 11 | dt[4] << 5 | (dt[5] // 2) 566 extra = [] 567 if zinfo.file_size > ZIP64_LIMIT \ 568 or zinfo.compress_size > ZIP64_LIMIT: 569 extra.append(zinfo.file_size) 570 extra.append(zinfo.compress_size) 571 file_size = 0xffffffff 572 compress_size = 0xffffffff 573 else: 574 file_size = zinfo.file_size 575 compress_size = zinfo.compress_size 576 577 if zinfo.header_offset > ZIP64_LIMIT: 578 extra.append(zinfo.header_offset) 579 header_offset = 0xffffffffL 580 else: 581 header_offset = zinfo.header_offset 582 583 extra_data = zinfo.extra 584 if extra: 585 # Append a ZIP64 field to the extra's 586 extra_data = struct.pack( 587 '<HH' + 'Q'*len(extra), 588 1, 8*len(extra), *extra) + extra_data 589 590 extract_version = max(45, zinfo.extract_version) 591 create_version = max(45, zinfo.create_version) 592 else: 593 extract_version = zinfo.extract_version 594 create_version = zinfo.create_version 595 596 try: 597 filename, flag_bits = zinfo._encodeFilenameFlags() 598 centdir = struct.pack(structCentralDir, 599 stringCentralDir, create_version, 600 zinfo.create_system, extract_version, zinfo.reserved, 601 flag_bits, zinfo.compress_type, dostime, dosdate, 602 zinfo.CRC, compress_size, file_size, 603 len(filename), len(extra_data), len(zinfo.comment), 604 0, zinfo.internal_attr, zinfo.external_attr, 605 header_offset) 606 except DeprecationWarning: 607 print >>sys.stderr, (structCentralDir, 608 stringCentralDir, create_version, 609 zinfo.create_system, extract_version, zinfo.reserved, 610 zinfo.flag_bits, zinfo.compress_type, dostime, dosdate, 611 zinfo.CRC, compress_size, file_size, 612 len(zinfo.filename), len(extra_data), len(zinfo.comment), 613 0, zinfo.internal_attr, zinfo.external_attr, 614 header_offset) 615 raise 616 self.fp.write(centdir) 617 self.fp.write(filename) 618 self.fp.write(extra_data) 619 self.fp.write(zinfo.comment) 620 621 pos2 = self.fp.tell() 622 # Write end-of-zip-archive record 623 centDirCount = len(self.filelist) 624 centDirSize = pos2 - pos1 625 centDirOffset = pos1 626 requires_zip64 = None 627 if centDirCount > ZIP_FILECOUNT_LIMIT: 628 requires_zip64 = "Files count" 629 elif centDirOffset > ZIP64_LIMIT: 630 requires_zip64 = "Central directory offset" 631 elif centDirSize > ZIP64_LIMIT: 632 requires_zip64 = "Central directory size" 633 if requires_zip64: 634 # Need to write the ZIP64 end-of-archive records 635 if not self._allowZip64: 636 raise LargeZipFile(requires_zip64 + 637 " would require ZIP64 extensions") 638 zip64endrec = struct.pack( 639 structEndArchive64, stringEndArchive64, 640 44, 45, 45, 0, 0, centDirCount, centDirCount, 641 centDirSize, centDirOffset) 642 self.fp.write(zip64endrec) 643 644 zip64locrec = struct.pack( 645 structEndArchive64Locator, 646 stringEndArchive64Locator, 0, pos2, 1) 647 self.fp.write(zip64locrec) 648 centDirCount = min(centDirCount, 0xFFFF) 649 centDirSize = min(centDirSize, 0xFFFFFFFF) 650 centDirOffset = min(centDirOffset, 0xFFFFFFFF) 651 652 endrec = struct.pack(structEndArchive, stringEndArchive, 653 0, 0, centDirCount, centDirCount, 654 centDirSize, centDirOffset, len(self._comment)) 655 self.fp.write(endrec) 656 self.fp.write(self._comment) 657 self.fp.flush() 658 finally: 659 fp = self.fp 660 self.fp = None 661 if not self._filePassed: 662 fp.close() 663 664 ZipFile 665 666 ZipFile 源碼
1 class TarFile(object): 2 """The TarFile Class provides an interface to tar archives. 3 """ 4 5 debug = 0 # May be set from 0 (no msgs) to 3 (all msgs) 6 7 dereference = False # If true, add content of linked file to the 8 # tar file, else the link. 9 10 ignore_zeros = False # If true, skips empty or invalid blocks and 11 # continues processing. 12 13 errorlevel = 1 # If 0, fatal errors only appear in debug 14 # messages (if debug >= 0). If > 0, errors 15 # are passed to the caller as exceptions. 16 17 format = DEFAULT_FORMAT # The format to use when creating an archive. 18 19 encoding = ENCODING # Encoding for 8-bit character strings. 20 21 errors = None # Error handler for unicode conversion. 22 23 tarinfo = TarInfo # The default TarInfo class to use. 24 25 fileobject = ExFileObject # The default ExFileObject class to use. 26 27 def __init__(self, name=None, mode="r", fileobj=None, format=None, 28 tarinfo=None, dereference=None, ignore_zeros=None, encoding=None, 29 errors=None, pax_headers=None, debug=None, errorlevel=None): 30 """Open an (uncompressed) tar archive `name'. `mode' is either 'r' to 31 read from an existing archive, 'a' to append data to an existing 32 file or 'w' to create a new file overwriting an existing one. `mode' 33 defaults to 'r'. 34 If `fileobj' is given, it is used for reading or writing data. If it 35 can be determined, `mode' is overridden by `fileobj's mode. 36 `fileobj' is not closed, when TarFile is closed. 37 """ 38 modes = {"r": "rb", "a": "r+b", "w": "wb"} 39 if mode not in modes: 40 raise ValueError("mode must be 'r', 'a' or 'w'") 41 self.mode = mode 42 self._mode = modes[mode] 43 44 if not fileobj: 45 if self.mode == "a" and not os.path.exists(name): 46 # Create nonexistent files in append mode. 47 self.mode = "w" 48 self._mode = "wb" 49 fileobj = bltn_open(name, self._mode) 50 self._extfileobj = False 51 else: 52 if name is None and hasattr(fileobj, "name"): 53 name = fileobj.name 54 if hasattr(fileobj, "mode"): 55 self._mode = fileobj.mode 56 self._extfileobj = True 57 self.name = os.path.abspath(name) if name else None 58 self.fileobj = fileobj 59 60 # Init attributes. 61 if format is not None: 62 self.format = format 63 if tarinfo is not None: 64 self.tarinfo = tarinfo 65 if dereference is not None: 66 self.dereference = dereference 67 if ignore_zeros is not None: 68 self.ignore_zeros = ignore_zeros 69 if encoding is not None: 70 self.encoding = encoding 71 72 if errors is not None: 73 self.errors = errors 74 elif mode == "r": 75 self.errors = "utf-8" 76 else: 77 self.errors = "strict" 78 79 if pax_headers is not None and self.format == PAX_FORMAT: 80 self.pax_headers = pax_headers 81 else: 82 self.pax_headers = {} 83 84 if debug is not None: 85 self.debug = debug 86 if errorlevel is not None: 87 self.errorlevel = errorlevel 88 89 # Init datastructures. 90 self.closed = False 91 self.members = [] # list of members as TarInfo objects 92 self._loaded = False # flag if all members have been read 93 self.offset = self.fileobj.tell() 94 # current position in the archive file 95 self.inodes = {} # dictionary caching the inodes of 96 # archive members already added 97 98 try: 99 if self.mode == "r": 100 self.firstmember = None 101 self.firstmember = self.next() 102 103 if self.mode == "a": 104 # Move to the end of the archive, 105 # before the first empty block. 106 while True: 107 self.fileobj.seek(self.offset) 108 try: 109 tarinfo = self.tarinfo.fromtarfile(self) 110 self.members.append(tarinfo) 111 except EOFHeaderError: 112 self.fileobj.seek(self.offset) 113 break 114 except HeaderError, e: 115 raise ReadError(str(e)) 116 117 if self.mode in "aw": 118 self._loaded = True 119 120 if self.pax_headers: 121 buf = self.tarinfo.create_pax_global_header(self.pax_headers.copy()) 122 self.fileobj.write(buf) 123 self.offset += len(buf) 124 except: 125 if not self._extfileobj: 126 self.fileobj.close() 127 self.closed = True 128 raise 129 130 def _getposix(self): 131 return self.format == USTAR_FORMAT 132 def _setposix(self, value): 133 import warnings 134 warnings.warn("use the format attribute instead", DeprecationWarning, 135 2) 136 if value: 137 self.format = USTAR_FORMAT 138 else: 139 self.format = GNU_FORMAT 140 posix = property(_getposix, _setposix) 141 142 #-------------------------------------------------------------------------- 143 # Below are the classmethods which act as alternate constructors to the 144 # TarFile class. The open() method is the only one that is needed for 145 # public use; it is the "super"-constructor and is able to select an 146 # adequate "sub"-constructor for a particular compression using the mapping 147 # from OPEN_METH. 148 # 149 # This concept allows one to subclass TarFile without losing the comfort of 150 # the super-constructor. A sub-constructor is registered and made available 151 # by adding it to the mapping in OPEN_METH. 152 153 @classmethod 154 def open(cls, name=None, mode="r", fileobj=None, bufsize=RECORDSIZE, **kwargs): 155 """Open a tar archive for reading, writing or appending. Return 156 an appropriate TarFile class. 157 158 mode: 159 'r' or 'r:*' open for reading with transparent compression 160 'r:' open for reading exclusively uncompressed 161 'r:gz' open for reading with gzip compression 162 'r:bz2' open for reading with bzip2 compression 163 'a' or 'a:' open for appending, creating the file if necessary 164 'w' or 'w:' open for writing without compression 165 'w:gz' open for writing with gzip compression 166 'w:bz2' open for writing with bzip2 compression 167 168 'r|*' open a stream of tar blocks with transparent compression 169 'r|' open an uncompressed stream of tar blocks for reading 170 'r|gz' open a gzip compressed stream of tar blocks 171 'r|bz2' open a bzip2 compressed stream of tar blocks 172 'w|' open an uncompressed stream for writing 173 'w|gz' open a gzip compressed stream for writing 174 'w|bz2' open a bzip2 compressed stream for writing 175 """ 176 177 if not name and not fileobj: 178 raise ValueError("nothing to open") 179 180 if mode in ("r", "r:*"): 181 # Find out which *open() is appropriate for opening the file. 182 for comptype in cls.OPEN_METH: 183 func = getattr(cls, cls.OPEN_METH[comptype]) 184 if fileobj is not None: 185 saved_pos = fileobj.tell() 186 try: 187 return func(name, "r", fileobj, **kwargs) 188 except (ReadError, CompressionError), e: 189 if fileobj is not None: 190 fileobj.seek(saved_pos) 191 continue 192 raise ReadError("file could not be opened successfully") 193 194 elif ":" in mode: 195 filemode, comptype = mode.split(":", 1) 196 filemode = filemode or "r" 197 comptype = comptype or "tar" 198 199 # Select the *open() function according to 200 # given compression. 201 if comptype in cls.OPEN_METH: 202 func = getattr(cls, cls.OPEN_METH[comptype]) 203 else: 204 raise CompressionError("unknown compression type %r" % comptype) 205 return func(name, filemode, fileobj, **kwargs) 206 207 elif "|" in mode: 208 filemode, comptype = mode.split("|", 1) 209 filemode = filemode or "r" 210 comptype = comptype or "tar" 211 212 if filemode not in ("r", "w"): 213 raise ValueError("mode must be 'r' or 'w'") 214 215 stream = _Stream(name, filemode, comptype, fileobj, bufsize) 216 try: 217 t = cls(name, filemode, stream, **kwargs) 218 except: 219 stream.close() 220 raise 221 t._extfileobj = False 222 return t 223 224 elif mode in ("a", "w"): 225 return cls.taropen(name, mode, fileobj, **kwargs) 226 227 raise ValueError("undiscernible mode") 228 229 @classmethod 230 def taropen(cls, name, mode="r", fileobj=None, **kwargs): 231 """Open uncompressed tar archive name for reading or writing. 232 """ 233 if mode not in ("r", "a", "w"): 234 raise ValueError("mode must be 'r', 'a' or 'w'") 235 return cls(name, mode, fileobj, **kwargs) 236 237 @classmethod 238 def gzopen(cls, name, mode="r", fileobj=None, compresslevel=9, **kwargs): 239 """Open gzip compressed tar archive name for reading or writing. 240 Appending is not allowed. 241 """ 242 if mode not in ("r", "w"): 243 raise ValueError("mode must be 'r' or 'w'") 244 245 try: 246 import gzip 247 gzip.GzipFile 248 except (ImportError, AttributeError): 249 raise CompressionError("gzip module is not available") 250 251 try: 252 fileobj = gzip.GzipFile(name, mode, compresslevel, fileobj) 253 except OSError: 254 if fileobj is not None and mode == 'r': 255 raise ReadError("not a gzip file") 256 raise 257 258 try: 259 t = cls.taropen(name, mode, fileobj, **kwargs) 260 except IOError: 261 fileobj.close() 262 if mode == 'r': 263 raise ReadError("not a gzip file") 264 raise 265 except: 266 fileobj.close() 267 raise 268 t._extfileobj = False 269 return t 270 271 @classmethod 272 def bz2open(cls, name, mode="r", fileobj=None, compresslevel=9, **kwargs): 273 """Open bzip2 compressed tar archive name for reading or writing. 274 Appending is not allowed. 275 """ 276 if mode not in ("r", "w"): 277 raise ValueError("mode must be 'r' or 'w'.") 278 279 try: 280 import bz2 281 except ImportError: 282 raise CompressionError("bz2 module is not available") 283 284 if fileobj is not None: 285 fileobj = _BZ2Proxy(fileobj, mode) 286 else: 287 fileobj = bz2.BZ2File(name, mode, compresslevel=compresslevel) 288 289 try: 290 t = cls.taropen(name, mode, fileobj, **kwargs) 291 except (IOError, EOFError): 292 fileobj.close() 293 if mode == 'r': 294 raise ReadError("not a bzip2 file") 295 raise 296 except: 297 fileobj.close() 298 raise 299 t._extfileobj = False 300 return t 301 302 # All *open() methods are registered here. 303 OPEN_METH = { 304 "tar": "taropen", # uncompressed tar 305 "gz": "gzopen", # gzip compressed tar 306 "bz2": "bz2open" # bzip2 compressed tar 307 } 308 309 #-------------------------------------------------------------------------- 310 # The public methods which TarFile provides: 311 312 def close(self): 313 """Close the TarFile. In write-mode, two finishing zero blocks are 314 appended to the archive. 315 """ 316 if self.closed: 317 return 318 319 if self.mode in "aw": 320 self.fileobj.write(NUL * (BLOCKSIZE * 2)) 321 self.offset += (BLOCKSIZE * 2) 322 # fill up the end with zero-blocks 323 # (like option -b20 for tar does) 324 blocks, remainder = divmod(self.offset, RECORDSIZE) 325 if remainder > 0: 326 self.fileobj.write(NUL * (RECORDSIZE - remainder)) 327 328 if not self._extfileobj: 329 self.fileobj.close() 330 self.closed = True 331 332 def getmember(self, name): 333 """Return a TarInfo object for member `name'. If `name' can not be 334 found in the archive, KeyError is raised. If a member occurs more 335 than once in the archive, its last occurrence is assumed to be the 336 most up-to-date version. 337 """ 338 tarinfo = self._getmember(name) 339 if tarinfo is None: 340 raise KeyError("filename %r not found" % name) 341 return tarinfo 342 343 def getmembers(self): 344 """Return the members of the archive as a list of TarInfo objects. The 345 list has the same order as the members in the archive. 346 """ 347 self._check() 348 if not self._loaded: # if we want to obtain a list of 349 self._load() # all members, we first have to 350 # scan the whole archive. 351 return self.members 352 353 def getnames(self): 354 """Return the members of the archive as a list of their names. It has 355 the same order as the list returned by getmembers(). 356 """ 357 return [tarinfo.name for tarinfo in self.getmembers()] 358 359 def gettarinfo(self, name=None, arcname=None, fileobj=None): 360 """Create a TarInfo object for either the file `name' or the file 361 object `fileobj' (using os.fstat on its file descriptor). You can 362 modify some of the TarInfo's attributes before you add it using 363 addfile(). If given, `arcname' specifies an alternative name for the 364 file in the archive. 365 """ 366 self._check("aw") 367 368 # When fileobj is given, replace name by 369 # fileobj's real name. 370 if fileobj is not None: 371 name = fileobj.name 372 373 # Building the name of the member in the archive. 374 # Backward slashes are converted to forward slashes, 375 # Absolute paths are turned to relative paths. 376 if arcname is None: 377 arcname = name 378 drv, arcname = os.path.splitdrive(arcname) 379 arcname = arcname.replace(os.sep, "/") 380 arcname = arcname.lstrip("/") 381 382 # Now, fill the TarInfo object with 383 # information specific for the file. 384 tarinfo = self.tarinfo() 385 tarinfo.tarfile = self 386 387 # Use os.stat or os.lstat, depending on platform 388 # and if symlinks shall be resolved. 389 if fileobj is None: 390 if hasattr(os, "lstat") and not self.dereference: 391 statres = os.lstat(name) 392 else: 393 statres = os.stat(name) 394 else: 395 statres = os.fstat(fileobj.fileno()) 396 linkname = "" 397 398 stmd = statres.st_mode 399 if stat.S_ISREG(stmd): 400 inode = (statres.st_ino, statres.st_dev) 401 if not self.dereference and statres.st_nlink > 1 and \ 402 inode in self.inodes and arcname != self.inodes[inode]: 403 # Is it a hardlink to an already 404 # archived file? 405 type = LNKTYPE 406 linkname = self.inodes[inode] 407 else: 408 # The inode is added only if its valid. 409 # For win32 it is always 0. 410 type = REGTYPE 411 if inode[0]: 412 self.inodes[inode] = arcname 413 elif stat.S_ISDIR(stmd): 414 type = DIRTYPE 415 elif stat.S_ISFIFO(stmd): 416 type = FIFOTYPE 417 elif stat.S_ISLNK(stmd): 418 type = SYMTYPE 419 linkname = os.readlink(name) 420 elif stat.S_ISCHR(stmd): 421 type = CHRTYPE 422 elif stat.S_ISBLK(stmd): 423 type = BLKTYPE 424 else: 425 return None 426 427 # Fill the TarInfo object with all 428 # information we can get. 429 tarinfo.name = arcname 430 tarinfo.mode = stmd 431 tarinfo.uid = statres.st_uid 432 tarinfo.gid = statres.st_gid 433 if type == REGTYPE: 434 tarinfo.size = statres.st_size 435 else: 436 tarinfo.size = 0L 437 tarinfo.mtime = statres.st_mtime 438 tarinfo.type = type 439 tarinfo.linkname = linkname 440 if pwd: 441 try: 442 tarinfo.uname = pwd.getpwuid(tarinfo.uid)[0] 443 except KeyError: 444 pass 445 if grp: 446 try: 447 tarinfo.gname = grp.getgrgid(tarinfo.gid)[0] 448 except KeyError: 449 pass 450 451 if type in (CHRTYPE, BLKTYPE): 452 if hasattr(os, "major") and hasattr(os, "minor"): 453 tarinfo.devmajor = os.major(statres.st_rdev) 454 tarinfo.devminor = os.minor(statres.st_rdev) 455 return tarinfo 456 457 def list(self, verbose=True): 458 """Print a table of contents to sys.stdout. If `verbose' is False, only 459 the names of the members are printed. If it is True, an `ls -l'-like 460 output is produced. 461 """ 462 self._check() 463 464 for tarinfo in self: 465 if verbose: 466 print filemode(tarinfo.mode), 467 print "%s/%s" % (tarinfo.uname or tarinfo.uid, 468 tarinfo.gname or tarinfo.gid), 469 if tarinfo.ischr() or tarinfo.isblk(): 470 print "%10s" % ("%d,%d" \ 471 % (tarinfo.devmajor, tarinfo.devminor)), 472 else: 473 print "%10d" % tarinfo.size, 474 print "%d-%02d-%02d %02d:%02d:%02d" \ 475 % time.localtime(tarinfo.mtime)[:6], 476 477 print tarinfo.name + ("/" if tarinfo.isdir() else ""), 478 479 if verbose: 480 if tarinfo.issym(): 481 print "->", tarinfo.linkname, 482 if tarinfo.islnk(): 483 print "link to", tarinfo.linkname, 484 print 485 486 def add(self, name, arcname=None, recursive=True, exclude=None, filter=None): 487 """Add the file `name' to the archive. `name' may be any type of file 488 (directory, fifo, symbolic link, etc.). If given, `arcname' 489 specifies an alternative name for the file in the archive. 490 Directories are added recursively by default. This can be avoided by 491 setting `recursive' to False. `exclude' is a function that should 492 return True for each filename to be excluded. `filter' is a function 493 that expects a TarInfo object argument and returns the changed 494 TarInfo object, if it returns None the TarInfo object will be 495 excluded from the archive. 496 """ 497 self._check("aw") 498 499 if arcname is None: 500 arcname = name 501 502 # Exclude pathnames. 503 if exclude is not None: 504 import warnings 505 warnings.warn("use the filter argument instead", 506 DeprecationWarning, 2) 507 if exclude(name): 508 self._dbg(2, "tarfile: Excluded %r" % name) 509 return 510 511 # Skip if somebody tries to archive the archive... 512 if self.name is not None and os.path.abspath(name) == self.name: 513 self._dbg(2, "tarfile: Skipped %r" % name) 514 return 515 516 self._dbg(1, name) 517 518 # Create a TarInfo object from the file. 519 tarinfo = self.gettarinfo(name, arcname) 520 521 if tarinfo is None: 522 self._dbg(1, "tarfile: Unsupported type %r" % name) 523 return 524 525 # Change or exclude the TarInfo object. 526 if filter is not None: 527 tarinfo = filter(tarinfo) 528 if tarinfo is None: 529 self._dbg(2, "tarfile: Excluded %r" % name) 530 return 531 532 # Append the tar header and data to the archive. 533 if tarinfo.isreg(): 534 with bltn_open(name, "rb") as f: 535 self.addfile(tarinfo, f) 536 537 elif tarinfo.isdir(): 538 self.addfile(tarinfo) 539 if recursive: 540 for f in os.listdir(name): 541 self.add(os.path.join(name, f), os.path.join(arcname, f), 542 recursive, exclude, filter) 543 544 else: 545 self.addfile(tarinfo) 546 547 def addfile(self, tarinfo, fileobj=None): 548 """Add the TarInfo object `tarinfo' to the archive. If `fileobj' is 549 given, tarinfo.size bytes are read from it and added to the archive. 550 You can create TarInfo objects using gettarinfo(). 551 On Windows platforms, `fileobj' should always be opened with mode 552 'rb' to avoid irritation about the file size. 553 """ 554 self._check("aw") 555 556 tarinfo = copy.copy(tarinfo) 557 558 buf = tarinfo.tobuf(self.format, self.encoding, self.errors) 559 self.fileobj.write(buf) 560 self.offset += len(buf) 561 562 # If there's data to follow, append it. 563 if fileobj is not None: 564 copyfileobj(fileobj, self.fileobj, tarinfo.size) 565 blocks, remainder = divmod(tarinfo.size, BLOCKSIZE) 566 if remainder > 0: 567 self.fileobj.write(NUL * (BLOCKSIZE - remainder)) 568 blocks += 1 569 self.offset += blocks * BLOCKSIZE 570 571 self.members.append(tarinfo) 572 573 def extractall(self, path=".", members=None): 574 """Extract all members from the archive to the current working 575 directory and set owner, modification time and permissions on 576 directories afterwards. `path' specifies a different directory 577 to extract to. `members' is optional and must be a subset of the 578 list returned by getmembers(). 579 """ 580 directories = [] 581 582 if members is None: 583 members = self 584 585 for tarinfo in members: 586 if tarinfo.isdir(): 587 # Extract directories with a safe mode. 588 directories.append(tarinfo) 589 tarinfo = copy.copy(tarinfo) 590 tarinfo.mode = 0700 591 self.extract(tarinfo, path) 592 593 # Reverse sort directories. 594 directories.sort(key=operator.attrgetter('name')) 595 directories.reverse() 596 597 # Set correct owner, mtime and filemode on directories. 598 for tarinfo in directories: 599 dirpath = os.path.join(path, tarinfo.name) 600 try: 601 self.chown(tarinfo, dirpath) 602 self.utime(tarinfo, dirpath) 603 self.chmod(tarinfo, dirpath) 604 except ExtractError, e: 605 if self.errorlevel > 1: 606 raise 607 else: 608 self._dbg(1, "tarfile: %s" % e) 609 610 def extract(self, member, path=""): 611 """Extract a member from the archive to the current working directory, 612 using its full name. Its file information is extracted as accurately 613 as possible. `member' may be a filename or a TarInfo object. You can 614 specify a different directory using `path'. 615 """ 616 self._check("r") 617 618 if isinstance(member, basestring): 619 tarinfo = self.getmember(member) 620 else: 621 tarinfo = member 622 623 # Prepare the link target for makelink(). 624 if tarinfo.islnk(): 625 tarinfo._link_target = os.path.join(path, tarinfo.linkname) 626 627 try: 628 self._extract_member(tarinfo, os.path.join(path, tarinfo.name)) 629 except EnvironmentError, e: 630 if self.errorlevel > 0: 631 raise 632 else: 633 if e.filename is None: 634 self._dbg(1, "tarfile: %s" % e.strerror) 635 else: 636 self._dbg(1, "tarfile: %s %r" % (e.strerror, e.filename)) 637 except ExtractError, e: 638 if self.errorlevel > 1: 639 raise 640 else: 641 self._dbg(1, "tarfile: %s" % e) 642 643 def extractfile(self, member): 644 """Extract a member from the archive as a file object. `member' may be 645 a filename or a TarInfo object. If `member' is a regular file, a 646 file-like object is returned. If `member' is a link, a file-like 647 object is constructed from the link's target. If `member' is none of 648 the above, None is returned. 649 The file-like object is read-only and provides the following 650 methods: read(), readline(), readlines(), seek() and tell() 651 """ 652 self._check("r") 653 654 if isinstance(member, basestring): 655 tarinfo = self.getmember(member) 656 else: 657 tarinfo = member 658 659 if tarinfo.isreg(): 660 return self.fileobject(self, tarinfo) 661 662 elif tarinfo.type not in SUPPORTED_TYPES: 663 # If a member's type is unknown, it is treated as a 664 # regular file. 665 return self.fileobject(self, tarinfo) 666 667 elif tarinfo.islnk() or tarinfo.issym(): 668 if isinstance(self.fileobj, _Stream): 669 # A small but ugly workaround for the case that someone tries 670 # to extract a (sym)link as a file-object from a non-seekable 671 # stream of tar blocks. 672 raise StreamError("cannot extract (sym)link as file object") 673 else: 674 # A (sym)link's file object is its target's file object. 675 return self.extractfile(self._find_link_target(tarinfo)) 676 else: 677 # If there's no data associated with the member (directory, chrdev, 678 # blkdev, etc.), return None instead of a file object. 679 return None 680 681 def _extract_member(self, tarinfo, targetpath): 682 """Extract the TarInfo object tarinfo to a physical 683 file called targetpath. 684 """ 685 # Fetch the TarInfo object for the given name 686 # and build the destination pathname, replacing 687 # forward slashes to platform specific separators. 688 targetpath = targetpath.rstrip("/") 689 targetpath = targetpath.replace("/", os.sep) 690 691 # Create all upper directories. 692 upperdirs = os.path.dirname(targetpath) 693 if upperdirs and not os.path.exists(upperdirs): 694 # Create directories that are not part of the archive with 695 # default permissions. 696 os.makedirs(upperdirs) 697 698 if tarinfo.islnk() or tarinfo.issym(): 699 self._dbg(1, "%s -> %s" % (tarinfo.name, tarinfo.linkname)) 700 else: 701 self._dbg(1, tarinfo.name) 702 703 if tarinfo.isreg(): 704 self.makefile(tarinfo, targetpath) 705 elif tarinfo.isdir(): 706 self.makedir(tarinfo, targetpath) 707 elif tarinfo.isfifo(): 708 self.makefifo(tarinfo, targetpath) 709 elif tarinfo.ischr() or tarinfo.isblk(): 710 self.makedev(tarinfo, targetpath) 711 elif tarinfo.islnk() or tarinfo.issym(): 712 self.makelink(tarinfo, targetpath) 713 elif tarinfo.type not in SUPPORTED_TYPES: 714 self.makeunknown(tarinfo, targetpath) 715 else: 716 self.makefile(tarinfo, targetpath) 717 718 self.chown(tarinfo, targetpath) 719 if not tarinfo.issym(): 720 self.chmod(tarinfo, targetpath) 721 self.utime(tarinfo, targetpath) 722 723 #-------------------------------------------------------------------------- 724 # Below are the different file methods. They are called via 725 # _extract_member() when extract() is called. They can be replaced in a 726 # subclass to implement other functionality. 727 728 def makedir(self, tarinfo, targetpath): 729 """Make a directory called targetpath. 730 """ 731 try: 732 # Use a safe mode for the directory, the real mode is set 733 # later in _extract_member(). 734 os.mkdir(targetpath, 0700) 735 except EnvironmentError, e: 736 if e.errno != errno.EEXIST: 737 raise 738 739 def makefile(self, tarinfo, targetpath): 740 """Make a file called targetpath. 741 """ 742 source = self.extractfile(tarinfo) 743 try: 744 with bltn_open(targetpath, "wb") as target: 745 copyfileobj(source, target) 746 finally: 747 source.close() 748 749 def makeunknown(self, tarinfo, targetpath): 750 """Make a file from a TarInfo object with an unknown type 751 at targetpath. 752 """ 753 self.makefile(tarinfo, targetpath) 754 self._dbg(1, "tarfile: Unknown file type %r, " \ 755 "extracted as regular file." % tarinfo.type) 756 757 def makefifo(self, tarinfo, targetpath): 758 """Make a fifo called targetpath. 759 """ 760 if hasattr(os, "mkfifo"): 761 os.mkfifo(targetpath) 762 else: 763 raise ExtractError("fifo not supported by system") 764 765 def makedev(self, tarinfo, targetpath): 766 """Make a character or block device called targetpath. 767 """ 768 if not hasattr(os, "mknod") or not hasattr(os, "makedev"): 769 raise ExtractError("special devices not supported by system") 770 771 mode = tarinfo.mode 772 if tarinfo.isblk(): 773 mode |= stat.S_IFBLK 774 else: 775 mode |= stat.S_IFCHR 776 777 os.mknod(targetpath, mode, 778 os.makedev(tarinfo.devmajor, tarinfo.devminor)) 779 780 def makelink(self, tarinfo, targetpath): 781 """Make a (symbolic) link called targetpath. If it cannot be created 782 (platform limitation), we try to make a copy of the referenced file 783 instead of a link. 784 """ 785 if hasattr(os, "symlink") and hasattr(os, "link"): 786 # For systems that support symbolic and hard links. 787 if tarinfo.issym(): 788 if os.path.lexists(targetpath): 789 os.unlink(targetpath) 790 os.symlink(tarinfo.linkname, targetpath) 791 else: 792 # See extract(). 793 if os.path.exists(tarinfo._link_target): 794 if os.path.lexists(targetpath): 795 os.unlink(targetpath) 796 os.link(tarinfo._link_target, targetpath) 797 else: 798 self._extract_member(self._find_link_target(tarinfo), targetpath) 799 else: 800 try: 801 self._extract_member(self._find_link_target(tarinfo), targetpath) 802 except KeyError: 803 raise ExtractError("unable to resolve link inside archive") 804 805 def chown(self, tarinfo, targetpath): 806 """Set owner of targetpath according to tarinfo. 807 """ 808 if pwd and hasattr(os, "geteuid") and os.geteuid() == 0: 809 # We have to be root to do so. 810 try: 811 g = grp.getgrnam(tarinfo.gname)[2] 812 except KeyError: 813 g = tarinfo.gid 814 try: 815 u = pwd.getpwnam(tarinfo.uname)[2] 816 except KeyError: 817 u = tarinfo.uid 818 try: 819 if tarinfo.issym() and hasattr(os, "lchown"): 820 os.lchown(targetpath, u, g) 821 else: 822 if sys.platform != "os2emx": 823 os.chown(targetpath, u, g) 824 except EnvironmentError, e: 825 raise ExtractError("could not change owner") 826 827 def chmod(self, tarinfo, targetpath): 828 """Set file permissions of targetpath according to tarinfo. 829 """ 830 if hasattr(os, 'chmod'): 831 try: 832 os.chmod(targetpath, tarinfo.mode) 833 except EnvironmentError, e: 834 raise ExtractError("could not change mode") 835 836 def utime(self, tarinfo, targetpath): 837 """Set modification time of targetpath according to tarinfo. 838 """ 839 if not hasattr(os, 'utime'): 840 return 841 try: 842 os.utime(targetpath, (tarinfo.mtime, tarinfo.mtime)) 843 except EnvironmentError, e: 844 raise ExtractError("could not change modification time") 845 846 #-------------------------------------------------------------------------- 847 def next(self): 848 """Return the next member of the archive as a TarInfo object, when 849 TarFile is opened for reading. Return None if there is no more 850 available. 851 """ 852 self._check("ra") 853 if self.firstmember is not None: 854 m = self.firstmember 855 self.firstmember = None 856 return m 857 858 # Read the next block. 859 self.fileobj.seek(self.offset) 860 tarinfo = None 861 while True: 862 try: 863 tarinfo = self.tarinfo.fromtarfile(self) 864 except EOFHeaderError, e: 865 if self.ignore_zeros: 866 self._dbg(2, "0x%X: %s" % (self.offset, e)) 867 self.offset += BLOCKSIZE 868 continue 869 except InvalidHeaderError, e: 870 if self.ignore_zeros: 871 self._dbg(2, "0x%X: %s" % (self.offset, e)) 872 self.offset += BLOCKSIZE 873 continue 874 elif self.offset == 0: 875 raise ReadError(str(e)) 876 except EmptyHeaderError: 877 if self.offset == 0: 878 raise ReadError("empty file") 879 except TruncatedHeaderError, e: 880 if self.offset == 0: 881 raise ReadError(str(e)) 882 except SubsequentHeaderError, e: 883 raise ReadError(str(e)) 884 break 885 886 if tarinfo is not None: 887 self.members.append(tarinfo) 888 else: 889 self._loaded = True 890 891 return tarinfo 892 893 #-------------------------------------------------------------------------- 894 # Little helper methods: 895 896 def _getmember(self, name, tarinfo=None, normalize=False): 897 """Find an archive member by name from bottom to top. 898 If tarinfo is given, it is used as the starting point. 899 """ 900 # Ensure that all members have been loaded. 901 members = self.getmembers() 902 903 # Limit the member search list up to tarinfo. 904 if tarinfo is not None: 905 members = members[:members.index(tarinfo)] 906 907 if normalize: 908 name = os.path.normpath(name) 909 910 for member in reversed(members): 911 if normalize: 912 member_name = os.path.normpath(member.name) 913 else: 914 member_name = member.name 915 916 if name == member_name: 917 return member 918 919 def _load(self): 920 """Read through the entire archive file and look for readable 921 members. 922 """ 923 while True: 924 tarinfo = self.next() 925 if tarinfo is None: 926 break 927 self._loaded = True 928 929 def _check(self, mode=None): 930 """Check if TarFile is still open, and if the operation's mode 931 corresponds to TarFile's mode. 932 """ 933 if self.closed: 934 raise IOError("%s is closed" % self.__class__.__name__) 935 if mode is not None and self.mode not in mode: 936 raise IOError("bad operation for mode %r" % self.mode) 937 938 def _find_link_target(self, tarinfo): 939 """Find the target member of a symlink or hardlink member in the 940 archive. 941 """ 942 if tarinfo.issym(): 943 # Always search the entire archive. 944 linkname = "/".join(filter(None, (os.path.dirname(tarinfo.name), tarinfo.linkname))) 945 limit = None 946 else: 947 # Search the archive before the link, because a hard link is 948 # just a reference to an already archived file. 949 linkname = tarinfo.linkname 950 limit = tarinfo 951 952 member = self._getmember(linkname, tarinfo=limit, normalize=True) 953 if member is None: 954 raise KeyError("linkname %r not found" % linkname) 955 return member 956 957 def __iter__(self): 958 """Provide an iterator object. 959 """ 960 if self._loaded: 961 return iter(self.members) 962 else: 963 return TarIter(self) 964 965 def _dbg(self, level, msg): 966 """Write debugging output to sys.stderr. 967 """ 968 if level <= self.debug: 969 print >> sys.stderr, msg 970 971 def __enter__(self): 972 self._check() 973 return self 974 975 def __exit__(self, type, value, traceback): 976 if type is None: 977 self.close() 978 else: 979 # An exception occurred. We must not call close() because 980 # it would try to write end-of-archive blocks and padding. 981 if not self._extfileobj: 982 self.fileobj.close() 983 self.closed = True 984 # class TarFile 985 986 TarFile 987 988 TarFile 源碼
(6)json 和 pickle模塊:文件只能存二進制或字符串,不能存其餘類型,因此用到了用於序列化的兩個模塊
(7)shelve模塊:shelve模塊內部對pickle進行了封裝,shelve模塊是一個簡單的k,v將內存數據經過文件持久化的模塊,能夠持久化任何pickle可支持的python數據格式 (能夠存儲數據、獲取數據、給數據從新賦值)
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 #-Author-solo 4 import shelve 5 # k,v方式存儲數據 6 s = shelve.open("shelve_test") # 打開一個文件 7 tuple = (1, 2, 3, 4) 8 list = ['a', 'b', 'c', 'd'] 9 info = {"name": "lzl", "age": 18} 10 s["tuple"] = tuple # 持久化元組 11 s["list"] = list 12 s["info"] = info 13 s.close() 14 # 經過key獲取value值 15 d = shelve.open("shelve_test") # 打開一個文件 16 print(d["tuple"]) # 讀取 17 print(d.get("list")) 18 print(d.get("info")) 19 # (1, 2, 3, 4) 20 # ['a', 'b', 'c', 'd'] 21 # {'name': 'lzl', 'age': 18} 22 d.close() 23 # 循環打印key值 24 s = shelve.open("shelve_test") # 打開一個文件 25 for k in s.keys(): # 循環key值 26 print(k) 27 # list 28 # tuple 29 # info 30 s.close() 31 # 更新key的value值 32 s = shelve.open("shelve_test") # 打開一個文件 33 s.update({"list":[22,33]}) #從新賦值或者s["list"] = [22,33] 34 print(s["list"]) 35 #[22, 33] 36 s.close()
(8)xml模塊:xml是實現不一樣語言或程序之間進行數據交換的協議,跟json差很少,但json使用起來更簡單(經過<>節點來區別數據結構)
1 <?xml version="1.0"?><data> 2 <country name="Liechtenstein"> 3 <rank updated="yes">2</rank> 4 <year>2008</year> 5 <gdppc>141100</gdppc> 6 <neighbor name="Austria" direction="E"/> 7 <neighbor name="Switzerland" direction="W"/> 8 </country> 9 <country name="Singapore"> 10 <rank updated="yes">5</rank> 11 <year>2011</year> 12 <gdppc>59900</gdppc> 13 <neighbor name="Malaysia" direction="N"/> 14 </country> 15 <country name="Panama"> 16 <rank updated="yes">69</rank> 17 <year>2011</year> 18 <gdppc>13600</gdppc> 19 <neighbor name="Costa Rica" direction="W"/> 20 <neighbor name="Colombia" direction="E"/> 21 </country></data>
1 import xml.etree.ElementTree as ET 2 tree = ET.parse("xmltest.xml") 3 root = tree.getroot() 4 print(root.tag) 5 #遍歷xml文檔 6 for child in root: 7 print(child.tag, child.attrib) 8 for i in child: 9 print(i.tag,i.text) 10 #只遍歷year 節點 11 for node in root.iter('year'): 12 print(node.tag,node.text) 13 #修改 14 for node in root.iter('year'): 15 new_year = int(node.text) + 1 16 node.text = str(new_year) 17 node.set("updated","yes") 18 tree.write("xmltest.xml") 19 #刪除node 20 for country in root.findall('country'): 21 rank = int(country.find('rank').text) 22 if rank > 50: 23 root.remove(country) 24 tree.write('output.xml') 25 26 ###########本身建立xml文檔 27 import xml.etree.ElementTree as ET 28 new_xml = ET.Element("namelist") 29 name = ET.SubElement(new_xml,"name",attrib={"enrolled":"yes"}) 30 age = ET.SubElement(name,"age",attrib={"checked":"no"}) 31 sex = ET.SubElement(name,"sex") 32 sex.text = '33' 33 name2 = ET.SubElement(new_xml,"name",attrib={"enrolled":"no"}) 34 age = ET.SubElement(name2,"age") 35 age.text = '19' 36 et = ET.ElementTree(new_xml) #生成文檔對象 37 et.write("test.xml", encoding="utf-8",xml_declaration=True) 38 ET.dump(new_xml) #打印生成的格式
(9)configparser模塊:用於生成和修改配置文檔(不多在程序中修改配置文件)
(10)hashlib模塊:用於加密相關的操做,3.x裏代替了md5模塊和sha模塊,主要提供 SHA1, SHA224, SHA256, SHA384, SHA512 ,MD5 算法
1 import hashlib 2 m = hashlib.md5() 3 m.update(b"Hello") 4 m.update(b"It's me") 5 print(m.digest()) 6 m.update(b"It's been a long time since last time we ...") 7 print(m.digest()) #2進制格式hash 8 print(len(m.hexdigest())) #16進制格式hash 9 ''' 10 def digest(self, *args, **kwargs): # real signature unknown 11 """ Return the digest value as a string of binary data. """ 12 pass 13 def hexdigest(self, *args, **kwargs): # real signature unknown 14 """ Return the digest value as a string of hexadecimal digits. """ 15 pass 16 ''' 17 import hashlib 18 # ######## md5 ######## 19 hash = hashlib.md5() 20 hash.update('admin') 21 print(hash.hexdigest()) 22 # ######## sha1 ######## 23 hash = hashlib.sha1() 24 hash.update('admin') 25 print(hash.hexdigest()) 26 # ######## sha256 ######## 27 hash = hashlib.sha256() 28 hash.update('admin') 29 print(hash.hexdigest()) 30 # ######## sha384 ######## 31 hash = hashlib.sha384() 32 hash.update('admin') 33 print(hash.hexdigest()) 34 # ######## sha512 ######## 35 hash = hashlib.sha512() 36 hash.update('admin') 37 print(hash.hexdigest())
1 import hmac 2 h = hmac.new('wueiqi') 3 h.update('hellowo') 4 print h.hexdigest()
(11)re模塊:用於對python的正則表達式的操做;匹配(動態模糊的匹配);關鍵是匹配條件
1 '.' 默認匹配除\n以外的任意一個字符,若指定flag DOTALL,則匹配任意字符,包括換行 2 '^' 匹配字符開頭,若指定flags MULTILINE,這種也能夠匹配上(r"^a","\nabc\neee",flags=re.MULTILINE) 3 '$' 匹配字符結尾,或e.search("foo$","bfoo\nsdfsf",flags=re.MULTILINE).group()也能夠 4 '*' 匹配*號前的字符0次或屢次,re.findall("ab*","cabb3abcbbac") 結果爲['abb', 'ab', 'a'] 5 '+' 匹配前一個字符1次或屢次,re.findall("ab+","ab+cd+abb+bba") 結果['ab', 'abb'] 6 '?' 匹配前一個字符1次或0次 7 '{m}' 匹配前一個字符m次 8 '{n,m}' 匹配前一個字符n到m次,re.findall("ab{1,3}","abb abc abbcbbb") 結果'abb', 'ab', 'abb'] 9 '|' 匹配|左或|右的字符,re.search("abc|ABC","ABCBabcCD").group() 結果'ABC' 10 '(...)' 分組匹配,re.search("(abc){2}a(123|456)c", "abcabca456c").group() 結果 abcabca456c 11 '[a-z]' 匹配a到z任意一個字符 12 '[^()]' 匹配除()之外的任意一個字符 13 '\A' 只從字符開頭匹配,re.search("\Aabc","alexabc") 是匹配不到的 14 '\Z' 匹配字符結尾,同$ 15 '\d' 匹配數字0-9 16 '\D' 匹配非數字 17 '\w' 匹配[A-Za-z0-9] 18 '\W' 匹配非[A-Za-z0-9] 19 '\s' 匹配空白字符、\t、\n、\r , re.search("\s+","ab\tc1\n3").group() 結果 '\t' 20 '(?P<name>...)' 分組匹配 re.search("(?P<province>[0-9]{4})(?P<city>[0-9]{2})(?P<birthday>[0-9]{4})","371481199306143242").groupdict("city") 21 結果{'province': '3714', 'city': '81', 'birthday': '1993'}
①、match:從起始位置開始去匹配
1 #match 2 import re 3 obj = re.match('\d+', '123uua123sf') #從第一個字符開始匹配一個到多個數字 4 print(obj) 5 #<_sre.SRE_Match object; span=(0, 3), match='123'> 6 if obj: #若是有匹配到字符則執行,爲空不執行 7 print(obj.group()) #打印匹配到的內容 8 #123
②、search:最前面去匹配(不必定是最開始位置),匹配最前
1 #search 2 import re 3 obj = re.search('\d+', 'a123uu234asf') #從數字開始匹配一個到多個數字 4 print(obj) 5 #<_sre.SRE_Match object; span=(1, 4), match='123'> 6 if obj: #若是有匹配到字符則執行,爲空不執行 7 print(obj.group()) #打印匹配到的內容 8 #123 9 import re 10 obj = re.search('\([^()]+\)', 'sdds(a1fwewe2(3uusfdsf2)34as)f') #匹配最裏面()的內容 11 print(obj) 12 #<_sre.SRE_Match object; span=(13, 24), match='(3uusfdsf2)'> 13 if obj: #若是有匹配到字符則執行,爲空不執行 14 print(obj.group()) #打印匹配到的內容 15 #(3uusfdsf2)
③、group與groups的區別
1 #group與groups的區別 2 import re 3 a = "123abc456" 4 b = re.search("([0-9]*)([a-z]*)([0-9]*)", a) 5 print(b) 6 #<_sre.SRE_Match object; span=(0, 9), match='123abc456'> 7 print(b.group()) 8 #123abc456 9 print(b.group(0)) 10 #123abc456 11 print(b.group(1)) 12 #123 13 print(b.group(2)) 14 #abc 15 print(b.group(3)) 16 #456 17 print(b.groups()) 18 #('123', 'abc', '456')
④、findall上述兩中方式均用於匹配單值,即:只能匹配字符串中的一個,若是想要匹配到字符串中全部符合條件的元素,則須要使用 findall;findall沒有group 用法
1 #findall 2 import re 3 obj = re.findall('\d+', 'a123uu234asf') #匹配多個 4 if obj: #若是有匹配到字符則執行,爲空不執行 5 print(obj) #生成的內容爲列表 6 #['123', '234']
⑤、sub:用於替換匹配的字符串
1 #sub 2 import re 3 content = "123abc456" 4 new_content = re.sub('\d+', 'ABC', content) 5 print(new_content) 6 #ABCabcABC
⑥、split:根據指定匹配進行分組(分割)
1 #split 2 import re 3 content = "1 - 2 * ((60-30+1*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2) )" 4 new_content = re.split('\*', content) #用*進行分割,分割爲列表 5 print(new_content) 6 #['1 - 2 ', ' ((60-30+1', '(9-2', '5/3+7/3', '99/4', '2998+10', '568/14))-(-4', '3)/(16-3', '2) )'] 7 content = "'1 - 2 * ((60-30+1*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2) )'" 8 new_content = re.split('[\+\-\*\/]+', content) 9 # new_content = re.split('\*', content, 1) 10 print(new_content) 11 #["'1 ", ' 2 ', ' ((60', '30', '1', '(9', '2', '5', '3', '7', '3', '99', '4', '2998', '10', '568', '14))', 12 # '(', '4', '3)', '(16', '3', "2) )'"] 13 inpp = '1-2*((60-30 +(-40-5)*(9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2))' 14 inpp = re.sub('\s*','',inpp) #把空白字符去掉 15 print(inpp) 16 new_content = re.split('\(([\+\-\*\/]?\d+[\+\-\*\/]?\d+){1}\)', inpp, 1) 17 print(new_content) 18 #['1-2*((60-30+', '-40-5', '*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))']
(12)urllib模塊:提供了一系列用於操做URL的功能(利用程序去執行各類HTTP請求。若是要模擬瀏覽器完成特定功能,須要把請求假裝成瀏覽器。假裝的方法是先監控瀏覽器發出的請求,再根據瀏覽器的請求頭來假裝,User-Agent頭就是用來標識瀏覽器的。)
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 #-Author-solo 4 import urllib.request 5 def getdata(): 6 url = "http://www.baidu.com" 7 data = urllib.request.urlopen(url).read() 8 data = data.decode("utf-8") 9 print(data) 10 getdata() 11 12 ###urlopen返回的類文件對象支持close、read、readline、和readlines方法
12、面向對象
面向過程編程:經過代碼的層層堆積來實現功能。不易迭代和維護。
函數式編程:將某功能代碼封裝到函數中,僅調用函數便可
面向對象編程:利用「類」和「對象」來建立各類模型來實現對真實世界的描述;使用面向對象編程的緣由一方面是由於它可使程序的維護和擴展變得更簡單,而且能夠大大提升程序開發效率 ,另外,基於面向對象的程序可使它人更加容易理解你的代碼邏輯,從而使團隊開發變得更從容。
1 #經典類 2 class A(): 3 def __init__(self): 4 print("A") 5 class B(A): 6 pass 7 class C(A): 8 def __init__(self): 9 print("C") 10 class D(B,C): 11 pass 12 obj = D() 13 #A 14 #新式類 15 class A(object): 16 def __init__(self): 17 print("A") 18 class B(A): 19 pass 20 class C(A): 21 def __init__(self): 22 print("C") 23 class D(B,C): 24 pass 25 obj = D() 26 #C
1 #屬性方法 2 class Flight(object): 3 def __init__(self, name): 4 self.flight_name = name 5 def checking_status(self): 6 print("checking flight %s status " % self.flight_name) 7 return 1 8 @property 9 def flight_status(self): 10 status = self.checking_status() 11 if status == 0: 12 print("flight got canceled...") 13 elif status == 1: 14 print("flight is arrived...") 15 elif status == 2: 16 print("flight has departured already...") 17 else: 18 print("cannot confirm the flight status...,please check later") 19 @flight_status.setter # 修改 執行修改操做時觸發 20 def flight_status(self, status): 21 status_dic = { 22 0: "canceled", 23 1:"arrived", 24 2: "departured" 25 } 26 print("\033[31;1mHas changed the flight status to \033[0m", status_dic.get(status)) 27 @flight_status.deleter # 刪除 28 def flight_status(self): 29 print("status got removed...") 30 f = Flight("CA980") 31 f.flight_status = 0 # 觸發@flight_status.setter 只執行setter裝飾的代碼 32 del f.flight_status # 觸發@flight_status.deleter 只執行deleter裝飾的代碼 33 34 #執行相應的操做,觸發相應的裝飾器,此時不會再觸發原來的屬性,只執行裝飾器下面的代碼,須要作相應的操做可在代碼塊裏添加(修改,刪除);只是觸發了而已,裝飾器並無作什麼操做
類的特殊成員方法:
① __doc__ 表示類的描述信息
1 #__doc__ 2 class Foo: 3 """ 描述類信息,這是用於看片的神奇 """ 4 def func(self): 5 pass 6 print(Foo.__doc__) 7 # 描述類信息,這是用於看片的神奇
② __module__ 和 __class__
__module__ 表示當前操做的對象在哪一個模塊
__class__ 表示當前操做的對象的類是什麼
1 # __module__ 和 __class__ 2 class Foo: 3 """ 描述類信息,這是用於看片的神奇 """ 4 def func(self): 5 pass 6 A = Foo() 7 print(A.__module__) 8 print(A.__class__) 9 # __main__ 10 # <class '__main__.Foo'>
③ __init__ 構造方法,經過類建立對象時,自動觸發執行
④ __del__析構方法,當對象在內存中被釋放時,自動觸發執行
⑤ __call__ 對象後面加括號,觸發執行
注:__init__的執行是由建立對象觸發的,即:對象 = 類名() ;而對於 __call__ 方法的執行是由對象後加括號觸發的,即:對象() 或者 類()()
1 # __call__ 2 class Foo: 3 def __init__(self): 4 pass 5 def __call__(self, *args, **kwargs): 6 print('__call__') 7 obj = Foo() # 執行 __init__ 8 obj() # 執行 __call__ 9 #__call__
⑥ __dict__ 查看類或對象中的全部成員
1 class Province: 2 country = 'China' 3 def __init__(self, name, count): 4 self.name = name 5 self.count = count 6 def func(self, *args, **kwargs): 7 print('func') 8 # 獲取類的成員,即:靜態字段、方法、 9 print(Province.__dict__) 10 # 輸出:{'__init__': <function Province.__init__ at 0x0054D588>, '__dict__': <attribute '__dict__' of 'Province' objects>, 11 # '__doc__': None, 'func': <function Province.func at 0x0054D4B0>, '__weakref__': <attribute '__weakref__' of 'Province' objects>, 12 # 'country': 'China', '__module__': '__main__'} 13 obj1 = Province('HeBei', 10000) 14 print(obj1.__dict__) 15 # 獲取 對象obj1 的成員 16 # 輸出:{'count': 10000, 'name': 'HeBei'}
⑦ __str__ 若是一個類中定義了__str__方法,那麼在打印 對象 時,默認輸出該方法的返回值
1 #__str__ 2 class Foo: 3 def __str__(self): 4 return 'solo' 5 obj = Foo() 6 print(obj) #輸出__str__返回值 而不是內存地址 7 # 輸出:solo
⑧ __getitem__、__setitem__、__delitem__
用於索引操做,如字典。以上分別表示獲取、設置、刪除數據
1 #__getitem__、__setitem__、__delitem__ 2 class Foo(object): 3 def __getitem__(self, key): 4 print('__getitem__', key) 5 def __setitem__(self, key, value): 6 print('__setitem__', key, value) 7 def __delitem__(self, key): 8 print('__delitem__', key) 9 obj = Foo() 10 result = obj['k1'] # 自動觸發執行 __getitem__ 11 obj['k2'] = 'solo' # 自動觸發執行 __setitem__ 12 del obj['k1'] 13 # __getitem__ k1 14 # __setitem__ k2 solo 15 # __delitem__ k1
⑨ __new__ \ __metaclass__
1 print type(f) # 輸出:<class '__main__.Foo'> 表示,obj 對象由Foo類建立 2 print type(Foo) # 輸出:<type 'type'> 表示,Foo類對象由 type 類建立
f對象是Foo類的一個實例,Foo類對象是 type 類的一個實例,即:Foo類對象 是經過type類的構造方法建立
是由 type 類實例化產生那麼問題來了,類默認是由 type 類實例化產生,type類中如何實現的建立類?類又是如何建立對象?
答:類中有一個屬性 __metaclass__,其用來表示該類由 誰 來實例化建立,因此,咱們能夠爲 __metaclass__ 設置一個type類的派生類,從而查看 類 建立的過程
1 class MyType(type): 2 def __init__(self, what, bases=None, dict=None): 3 print("--MyType init---") 4 super(MyType, self).__init__(what, bases, dict) 5 def __call__(self, *args, **kwargs): 6 print("--MyType call---") 7 obj = self.__new__(self, *args, **kwargs) 8 self.__init__(obj, *args, **kwargs) 9 class Foo(object): 10 __metaclass__ = MyType 11 def __init__(self, name): 12 self.name = name 13 print("Foo ---init__") 14 def __new__(cls, *args, **kwargs): 15 print("Foo --new--") 16 return object.__new__(cls) 17 # 第一階段:解釋器從上到下執行代碼建立Foo類 18 # 第二階段:經過Foo類建立obj對象 19 obj = Foo("solo")
反射:經過字符串映射或修改程序運行時的狀態、屬性、方法。 有如下4個方法
① hasattr(obj,str) 判斷一個對象obj裏是否有對應的str字符串的方法
② getattr(obj,str) 根據字符串去獲取obj對象裏的對應的方法的內存地址
1 class Foo(object): 2 def __init__(self,name): 3 self.name = name 4 def func(self): 5 print("func",self.name) 6 obj = Foo("alex") 7 str = "func" 8 print(hasattr(obj,str)) # 檢查是否含有成員 有沒有obj.str屬性 9 if hasattr(obj,str): 10 getattr(obj,str)() #getattr(obj,str) = obj.str 11 # True 12 # func alex
③ setattr(obj,'y','z') obj.y = z 經過字符串添加屬性
1 def bulk(self): 2 print("%s is yelling"%self.name) 3 class Foo(object): 4 def __init__(self,name): 5 self.name = name 6 def func(self): 7 print("func",self.name) 8 obj = Foo("alex") 9 str = "talk" 10 print(hasattr(obj,str)) # 檢查是否含有成員 有沒有obj.str屬性 11 if hasattr(obj,str): 12 getattr(obj,str)() # getattr(obj,str) = obj.str 13 else: 14 setattr(obj,str,bulk) # setattr(obj,str,bulk 至關於 obj.str = bulk 15 getattr(obj,str)() 16 # False 17 # alex is yelling
④ delattr(obj,str) 刪除obj.str 經過字符串刪除屬性
1 class Foo(object): 2 def __init__(self,name): 3 self.name = name 4 def func(self): 5 print("func",self.name) 6 obj = Foo("alex") 7 str = "name" 8 if hasattr(obj,str): 9 delattr(obj,str) # 刪除屬性obj.str 10 print(obj.name) 11 # Traceback (most recent call last): 12 # File "C:/Users/L/PycharmProjects/s14/preview/Day7/main.py", line 40, in <module> 13 # print(obj.name) 14 # AttributeError: 'Foo' object has no attribute 'name'
十3、Python垃圾回收機制
概述:和許多其它的高級語言同樣,Python使用了垃圾回收器來自動銷燬那些再也不使用的對象。每一個對象都有一個引用計數,當這個引用計數爲0時Python可以安全地銷燬這個對象
問題點:因爲一次僅能有一個對象被回收,引用計數沒法回收循環引用的對象。
解決方案:弱引用:減小循環引用,減小內存中沒必要要的對象存在的數量。對象可能在任什麼時候刻被回收。