欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Python基礎(chǔ)語言學(xué)習(xí)筆記總結(jié)(精華)

 更新時間:2017年11月14日 11:58:05   作者:李小小小偉  
給大家分享一篇關(guān)于Python基礎(chǔ)學(xué)習(xí)內(nèi)容的學(xué)習(xí)筆記整理總結(jié)篇,里面匯集了學(xué)習(xí)Python基礎(chǔ)語言的難點(diǎn)和技巧,分享給大家。

以下是Python基礎(chǔ)學(xué)習(xí)內(nèi)容的學(xué)習(xí)筆記的全部內(nèi)容,非常的詳細(xì),如果你對Python語言感興趣,并且針對性的系統(tǒng)學(xué)習(xí)一下基礎(chǔ)語言知識,下面的內(nèi)容能夠很好的滿足你的需求,如果感覺不錯,就收藏以后慢慢跟著學(xué)習(xí)吧。

一、變量賦值及命名規(guī)則

① 聲明一個變量及賦值

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# _author_soloLi
name1="solo"
name2=name1
print(name1,name2)
name1 = "hehe"
print(name1,name2)

#name1的值為hehe,name2的值為solo

② 變量命名的規(guī)則

1、變量名只能是 字母、數(shù)字或下劃線的任意組合
2、變量名的第一個字符不能是數(shù)字
3、以下關(guān)鍵字不能聲明為變量名['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']

二、字符編碼

python解釋器在加載 .py 文件中的代碼時,會對內(nèi)容進(jìn)行編碼(默認(rèn)ascill)

ASCII:最多只能用 8位來表示(一個字節(jié)),即:2**8 = 256,所以,ASCII碼最多只能表示 256 個符號。顯然ASCII碼無法將世界上的各種文字和符號全部表示。

Unicode:它為每種語言中的每個字符設(shè)定了統(tǒng)一并且唯一的二進(jìn)制編碼,規(guī)定雖有的字符和符號最少由 16 位來表示(2個字節(jié)),即:2 **16 = 65536,注:此處說的的是最少2個字節(jié),可能更多。

UTF-8:是對Unicode編碼的壓縮和優(yōu)化,他不再使用最少使用2個字節(jié),而是將所有的字符和符號進(jìn)行分類:ascii碼中的內(nèi)容用1個字節(jié)保存、歐洲的字符用2個字節(jié)保存,東亞的字符用3個字節(jié)保存...
注:python2.x版本,默認(rèn)支持的字符編碼為ASCll python3.x版本,默認(rèn)支持的是Unicode,不用聲明字符編碼可以直接顯示中文。

 擴(kuò)展:字符編碼和轉(zhuǎn)碼,bytes和str區(qū)別

    Python 3最重要的新特性大概要算是對文本和二進(jìn)制數(shù)據(jù)作了更為清晰的區(qū)分。文本總是Unicode,由str類型表示,二進(jìn)制數(shù)據(jù)則由bytes類型表示。Python 3不會以任意隱式的方式混用str和bytes(類似int和long之間自動轉(zhuǎn)換),正是這使得兩者的區(qū)分特別清晰。你不能拼接字符串和字節(jié)包,也無法在字節(jié)包里搜索字符串(反之亦然),也不能將字符串傳入?yún)?shù)為字節(jié)包的函數(shù)(反之亦然)。這是件好事。不管怎樣,字符串和字節(jié)包之間的界線是必然的,下面的圖解非常重要,務(wù)請牢記于心:

字符串可以編碼成字節(jié)包,而字節(jié)包可以解碼成字符串:

#!/usr/bin/env python
# -*- coding:utf-8 -*-
#-Author-solo
msg = "里約奧運(yùn)"
print(msg.encode("utf-8"))           #如果不指定編碼格式,默認(rèn)為utf-8
#b'\xe9\x87\x8c\xe7\xba\xa6\xe5\xa5\xa5\xe8\xbf\x90'
print(b'\xe9\x87\x8c\xe7\xba\xa6\xe5\xa5\xa5\xe8\xbf\x90'.decode("utf-8"))
#里約奧運(yùn)

為什么要進(jìn)行編碼和轉(zhuǎn)碼?

  由于每個國家電腦的字符編碼格式不統(tǒng)一(列中國:GBK),同一款軟件放到不同國家的電腦上會出現(xiàn)亂碼的情況,出現(xiàn)這種情況如何解決呢?! 當(dāng)然由于所有國家的電腦都支持Unicode萬國碼,那么我們可以把Unicode為跳板,先把字符編碼轉(zhuǎn)換為Unicode,在把Unicode轉(zhuǎn)換為另一個國家的字符編碼(例韓國),則不會出現(xiàn)亂碼的情況。當(dāng)然這里只是轉(zhuǎn)編碼集并不是翻譯成韓文不要弄混了。

① Python3.0進(jìn)行編碼轉(zhuǎn)換(默認(rèn)Unicode編碼)

name = "腳本之家"           #此時name為Unicode編碼
name1 = name.encode("utf-8")   #Unicode轉(zhuǎn)為UTF-8
name2 = name1.decode("utf-8")   #UTF-8轉(zhuǎn)為Unicode
name3 = name.encode("gbk")    #Unicode轉(zhuǎn)為GBK
name4 = name3.decode("gbk")   #GBK轉(zhuǎn)為Unicode

② Python2.0中的編碼轉(zhuǎn)換(默認(rèn)ascii編碼)

① 聲明字符編碼(utf-8)
# -*- coding:utf-8 -*-
name = "李偉"          #ascii碼里是沒有字符“你好”的,此時的name為uft-8
name1 = name.decode("utf-8")  #UTF-8轉(zhuǎn)為Unicode
name2 = name1.encode("gbk")   #Unicode轉(zhuǎn)為gbk
② 使用默認(rèn)字符編碼(ascii)
name = "nihao"       #英文字符,且第二行字符聲明去掉,此刻name為ascii碼
name1 = name.decode("ascii")   #ascii碼轉(zhuǎn)為unicode
name2 = name1.encode("utf-8") #unicode轉(zhuǎn)為utf-8
name3 =name1.encode("gbk")   #unicode轉(zhuǎn)為gbk

三、用戶交互及字符串拼接

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# _author_soloLi
# python2.X與python3.X區(qū)別:  python2.X raw_input = python3.X input
# 提示用戶輸入姓名、年齡、工作、工資并以信息列表的形式打印出
name = input("Please input your name:")
age = int(input("Please input your age:")) #str強(qiáng)制轉(zhuǎn)換為int
job = input("Please input your job:")
salary = input("Please input your salary:")
info1 = '''
------------ Info of %s ---------
Name:%s
Age:%d
Job:%s
Salary:%s
''' %(name,name,age,job,salary)   #%s檢測數(shù)據(jù)類型為字符串,%d檢測數(shù)據(jù)類型為整數(shù),%f檢測數(shù)據(jù)類型為浮點(diǎn)數(shù) 強(qiáng)制
print(info1)
# info2 = '''
# ------------ Info of {_Name} ---------
# Name:{_Name}
# Age:{_Age}
# Job:{_Job}
# Salary:{_Salary}
# ''' .format(_Name=name,
#       _Age=age,
#       _Job=job,
#       _Salary=salary)
# print(info2)
# info3 = '''
# ------------ Info of {0} ---------
# Name:{0}
# Age:{1}
# Job:{2}
# Salary:{3}
# ''' .format(name,age,job,salary)
# print(info3)

對比分析:
1、% :無法同時傳遞一個變量和元組,又是要加()來保證不拋出typeerror異常
2、+ :每增加一個一個+就會開辟一塊新的內(nèi)存空間
3、.fomat :不會出現(xiàn)上述問題,有時使用為了兼容Python2版本。如使用logging庫

四、循環(huán)語句(if、while、for、三元運(yùn)算)

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# _author_soloLi
################## if語句 ######################
# A = 66
#
# B = int(input("請輸入0-100的幸運(yùn)數(shù)字:"))
#
# if B == A:           #母級頂格寫
#   print ("恭喜你猜對了!")  #子級強(qiáng)制縮進(jìn)寫
# elif B > A :
#   print ("猜小了")
# else:
#   print ("猜大了")


################## while語句 ######################
# A = 66
# count = 0          # 設(shè)置初始值count=0
#
# while count < 3 :
#
#   B = int(input("請輸入0-100的數(shù)字:"))
#
#   if B == A:
#     print ("恭喜你猜對了!")
#     break
#   elif B > A :
#     print ("猜大了")
#   else:
#     print ("猜小了")
#   count += 1
# else:
#   print ("你猜的次數(shù)太多了!")


################## for語句 ######################
A = 66
i=1
for i in range(3):# while判斷count是否小于3,如果小于3則:
  print("i=",i)
  B = int(input("請輸入0-100的數(shù)字:"))
  if B == A:
    print ("恭喜你猜對了!")
    break
  elif B > A :
    print ("猜小了")
  else:
    print ("猜大了")
  i+=1
else:
  print ("你猜的次數(shù)太多了!")


################## 三元運(yùn)算 ######################
 # esult = 值1 if 條件 else 值2
 # 如果條件成立,那么將 “值1” 賦值給result變量,否則,將“值2”賦值給result變量


五、基本數(shù)據(jù)類型

一、整型
如: 18、73、84
類型常用功能:

abs(x)   #返回絕對值
x+y,x-y,x*y,x/y #加減乘除
x/y     #取商,浮點(diǎn)數(shù)相除保留余數(shù)
x//y    #取商,浮點(diǎn)數(shù)相除余數(shù)為0
x%y     #取余
x**y     #冪次方
cmp(x,y)  #兩個數(shù)比較,返回True或False相等則為0
coerce(x,y) #強(qiáng)制把兩個數(shù)生成一個元組
divmod(x,y) #相除得到商和余數(shù)組成的元組
float(x)  #轉(zhuǎn)換為浮點(diǎn)型
str(x)   #轉(zhuǎn)換為字符串
hex(x)   #轉(zhuǎn)換為16進(jìn)制
oct(x)   #轉(zhuǎn)換8進(jìn)制

更多功能:

class int(object):
  """
  int(x=0) -> int or long
  int(x, base=10) -> int or long
  
  Convert a number or string to an integer, or return 0 if no arguments
  are given. If x is floating point, the conversion truncates towards zero.
  If x is outside the integer range, the function returns a long instead.
  
  If x is not a number or if base is given, then x must be a string or
  Unicode object representing an integer literal in the given base. The
  literal can be preceded by '+' or '-' and be surrounded by whitespace.
  The base defaults to 10. Valid bases are 0 and 2-36. Base 0 means to
  interpret the base from the string as an integer literal.
  >>> int('0b100', base=0)
  """
  def bit_length(self): 
    """ 返回表示該數(shù)字的時占用的最少位數(shù) """
    """
    int.bit_length() -> int
    
    Number of bits necessary to represent self in binary.
    >>> bin(37)
    '0b100101'
    >>> (37).bit_length()
    """
    return 0

  def conjugate(self, *args, **kwargs): # real signature unknown
    """ 返回該復(fù)數(shù)的共軛復(fù)數(shù) """
    """ Returns self, the complex conjugate of any int. """
    pass

  def __abs__(self):
    """ 返回絕對值 """
    """ x.__abs__() <==> abs(x) """
    pass

  def __add__(self, y):
    """ x.__add__(y) <==> x+y """
    pass

  def __and__(self, y):
    """ x.__and__(y) <==> x&y """
    pass

  def __cmp__(self, y): 
    """ 比較兩個數(shù)大小 """
    """ x.__cmp__(y) <==> cmp(x,y) """
    pass

  def __coerce__(self, y):
    """ 強(qiáng)制生成一個元組 """ 
    """ x.__coerce__(y) <==> coerce(x, y) """
    pass

  def __divmod__(self, y): 
    """ 相除,得到商和余數(shù)組成的元組 """ 
    """ x.__divmod__(y) <==> divmod(x, y) """
    pass

  def __div__(self, y): 
    """ x.__div__(y) <==> x/y """
    pass

  def __float__(self): 
    """ 轉(zhuǎn)換為浮點(diǎn)類型 """ 
    """ x.__float__() <==> float(x) """
    pass

  def __floordiv__(self, y): 
    """ x.__floordiv__(y) <==> x//y """
    pass

  def __format__(self, *args, **kwargs): # real signature unknown
    pass

  def __getattribute__(self, name): 
    """ x.__getattribute__('name') <==> x.name """
    pass

  def __getnewargs__(self, *args, **kwargs): # real signature unknown
    """ 內(nèi)部調(diào)用 __new__方法或創(chuàng)建對象時傳入?yún)?shù)使用 """ 
    pass

  def __hash__(self): 
    """如果對象object為哈希表類型,返回對象object的哈希值。哈希值為整數(shù)。在字典查找中,哈希值用于快速比較字典的鍵。兩個數(shù)值如果相等,則哈希值也相等。"""
    """ x.__hash__() <==> hash(x) """
    pass

  def __hex__(self): 
    """ 返回當(dāng)前數(shù)的 十六進(jìn)制 表示 """ 
    """ x.__hex__() <==> hex(x) """
    pass

  def __index__(self): 
    """ 用于切片,數(shù)字無意義 """
    """ x[y:z] <==> x[y.__index__():z.__index__()] """
    pass

  def __init__(self, x, base=10): # known special case of int.__init__
    """ 構(gòu)造方法,執(zhí)行 x = 123 或 x = int(10) 時,自動調(diào)用,暫時忽略 """ 
    """
    int(x=0) -> int or long
    int(x, base=10) -> int or long
    
    Convert a number or string to an integer, or return 0 if no arguments
    are given. If x is floating point, the conversion truncates towards zero.
    If x is outside the integer range, the function returns a long instead.
    
    If x is not a number or if base is given, then x must be a string or
    Unicode object representing an integer literal in the given base. The
    literal can be preceded by '+' or '-' and be surrounded by whitespace.
    The base defaults to 10. Valid bases are 0 and 2-36. Base 0 means to
    interpret the base from the string as an integer literal.
    >>> int('0b100', base=0)
    # (copied from class doc)
    """
    pass

  def __int__(self): 
    """ 轉(zhuǎn)換為整數(shù) """ 
    """ x.__int__() <==> int(x) """
    pass

  def __invert__(self): 
    """ x.__invert__() <==> ~x """
    pass

  def __long__(self): 
    """ 轉(zhuǎn)換為長整數(shù) """ 
    """ x.__long__() <==> long(x) """
    pass

  def __lshift__(self, y): 
    """ x.__lshift__(y) <==> x<<y """
    pass

  def __mod__(self, y): 
    """ x.__mod__(y) <==> x%y """
    pass

  def __mul__(self, y): 
    """ x.__mul__(y) <==> x*y """
    pass

  def __neg__(self): 
    """ x.__neg__() <==> -x """
    pass

  @staticmethod # known case of __new__
  def __new__(S, *more): 
    """ T.__new__(S, ...) -> a new object with type S, a subtype of T """
    pass

  def __nonzero__(self): 
    """ x.__nonzero__() <==> x != 0 """
    pass

  def __oct__(self): 
    """ 返回改值的 八進(jìn)制 表示 """ 
    """ x.__oct__() <==> oct(x) """
    pass

  def __or__(self, y): 
    """ x.__or__(y) <==> x|y """
    pass

  def __pos__(self): 
    """ x.__pos__() <==> +x """
    pass

  def __pow__(self, y, z=None): 
    """ 冪,次方 """ 
    """ x.__pow__(y[, z]) <==> pow(x, y[, z]) """
    pass

  def __radd__(self, y): 
    """ x.__radd__(y) <==> y+x """
    pass

  def __rand__(self, y): 
    """ x.__rand__(y) <==> y&x """
    pass

  def __rdivmod__(self, y): 
    """ x.__rdivmod__(y) <==> divmod(y, x) """
    pass

  def __rdiv__(self, y): 
    """ x.__rdiv__(y) <==> y/x """
    pass

  def __repr__(self): 
    """轉(zhuǎn)化為解釋器可讀取的形式 """
    """ x.__repr__() <==> repr(x) """
    pass

  def __str__(self): 
    """轉(zhuǎn)換為人閱讀的形式,如果沒有適于人閱讀的解釋形式的話,則返回解釋器課閱讀的形式"""
    """ x.__str__() <==> str(x) """
    pass

  def __rfloordiv__(self, y): 
    """ x.__rfloordiv__(y) <==> y//x """
    pass

  def __rlshift__(self, y): 
    """ x.__rlshift__(y) <==> y<<x """
    pass

  def __rmod__(self, y): 
    """ x.__rmod__(y) <==> y%x """
    pass

  def __rmul__(self, y): 
    """ x.__rmul__(y) <==> y*x """
    pass

  def __ror__(self, y): 
    """ x.__ror__(y) <==> y|x """
    pass

  def __rpow__(self, x, z=None): 
    """ y.__rpow__(x[, z]) <==> pow(x, y[, z]) """
    pass

  def __rrshift__(self, y): 
    """ x.__rrshift__(y) <==> y>>x """
    pass

  def __rshift__(self, y): 
    """ x.__rshift__(y) <==> x>>y """
    pass

  def __rsub__(self, y): 
    """ x.__rsub__(y) <==> y-x """
    pass

  def __rtruediv__(self, y): 
    """ x.__rtruediv__(y) <==> y/x """
    pass

  def __rxor__(self, y): 
    """ x.__rxor__(y) <==> y^x """
    pass

  def __sub__(self, y): 
    """ x.__sub__(y) <==> x-y """
    pass

  def __truediv__(self, y): 
    """ x.__truediv__(y) <==> x/y """
    pass

  def __trunc__(self, *args, **kwargs): 
    """ 返回數(shù)值被截取為整形的值,在整形中無意義 """
    pass

  def __xor__(self, y): 
    """ x.__xor__(y) <==> x^y """
    pass

  denominator = property(lambda self: object(), lambda self, v: None, lambda self: None) # default
  """ 分母 = 1 """
  """the denominator of a rational number in lowest terms"""

  imag = property(lambda self: object(), lambda self, v: None, lambda self: None) # default
  """ 虛數(shù),無意義 """
  """the imaginary part of a complex number"""

  numerator = property(lambda self: object(), lambda self, v: None, lambda self: None) # default
  """ 分子 = 數(shù)字大小 """
  """the numerator of a rational number in lowest terms"""

  real = property(lambda self: object(), lambda self, v: None, lambda self: None) # default
  """ 實(shí)屬,無意義 """
  """the real part of a complex number"""

int

int

二、長整型
如:2147483649、9223372036854775807
類型常用功能:

#長整型功能與整形基本類似

class long(object):
  """
  long(x=0) -> long
  long(x, base=10) -> long
  
  Convert a number or string to a long integer, or return 0L if no arguments
  are given. If x is floating point, the conversion truncates towards zero.
  
  If x is not a number or if base is given, then x must be a string or
  Unicode object representing an integer literal in the given base. The
  literal can be preceded by '+' or '-' and be surrounded by whitespace.
  The base defaults to 10. Valid bases are 0 and 2-36. Base 0 means to
  interpret the base from the string as an integer literal.
  >>> int('0b100', base=0)
  4L
  """
  def bit_length(self): # real signature unknown; restored from __doc__
    """
    long.bit_length() -> int or long
    
    Number of bits necessary to represent self in binary.
    >>> bin(37L)
    '0b100101'
    >>> (37L).bit_length()
    """
    return 0

  def conjugate(self, *args, **kwargs): # real signature unknown
    """ Returns self, the complex conjugate of any long. """
    pass

  def __abs__(self): # real signature unknown; restored from __doc__
    """ x.__abs__() <==> abs(x) """
    pass

  def __add__(self, y): # real signature unknown; restored from __doc__
    """ x.__add__(y) <==> x+y """
    pass

  def __and__(self, y): # real signature unknown; restored from __doc__
    """ x.__and__(y) <==> x&y """
    pass

  def __cmp__(self, y): # real signature unknown; restored from __doc__
    """ x.__cmp__(y) <==> cmp(x,y) """
    pass

  def __coerce__(self, y): # real signature unknown; restored from __doc__
    """ x.__coerce__(y) <==> coerce(x, y) """
    pass

  def __divmod__(self, y): # real signature unknown; restored from __doc__
    """ x.__divmod__(y) <==> divmod(x, y) """
    pass

  def __div__(self, y): # real signature unknown; restored from __doc__
    """ x.__div__(y) <==> x/y """
    pass

  def __float__(self): # real signature unknown; restored from __doc__
    """ x.__float__() <==> float(x) """
    pass

  def __floordiv__(self, y): # real signature unknown; restored from __doc__
    """ x.__floordiv__(y) <==> x//y """
    pass

  def __format__(self, *args, **kwargs): # real signature unknown
    pass

  def __getattribute__(self, name): # real signature unknown; restored from __doc__
    """ x.__getattribute__('name') <==> x.name """
    pass

  def __getnewargs__(self, *args, **kwargs): # real signature unknown
    pass

  def __hash__(self): # real signature unknown; restored from __doc__
    """ x.__hash__() <==> hash(x) """
    pass

  def __hex__(self): # real signature unknown; restored from __doc__
    """ x.__hex__() <==> hex(x) """
    pass

  def __index__(self): # real signature unknown; restored from __doc__
    """ x[y:z] <==> x[y.__index__():z.__index__()] """
    pass

  def __init__(self, x=0): # real signature unknown; restored from __doc__
    pass

  def __int__(self): # real signature unknown; restored from __doc__
    """ x.__int__() <==> int(x) """
    pass

  def __invert__(self): # real signature unknown; restored from __doc__
    """ x.__invert__() <==> ~x """
    pass

  def __long__(self): # real signature unknown; restored from __doc__
    """ x.__long__() <==> long(x) """
    pass

  def __lshift__(self, y): # real signature unknown; restored from __doc__
    """ x.__lshift__(y) <==> x<<y """
    pass

  def __mod__(self, y): # real signature unknown; restored from __doc__
    """ x.__mod__(y) <==> x%y """
    pass

  def __mul__(self, y): # real signature unknown; restored from __doc__
    """ x.__mul__(y) <==> x*y """
    pass

  def __neg__(self): # real signature unknown; restored from __doc__
    """ x.__neg__() <==> -x """
    pass

  @staticmethod # known case of __new__
  def __new__(S, *more): # real signature unknown; restored from __doc__
    """ T.__new__(S, ...) -> a new object with type S, a subtype of T """
    pass

  def __nonzero__(self): # real signature unknown; restored from __doc__
    """ x.__nonzero__() <==> x != 0 """
    pass

  def __oct__(self): # real signature unknown; restored from __doc__
    """ x.__oct__() <==> oct(x) """
    pass

  def __or__(self, y): # real signature unknown; restored from __doc__
    """ x.__or__(y) <==> x|y """
    pass

  def __pos__(self): # real signature unknown; restored from __doc__
    """ x.__pos__() <==> +x """
    pass

  def __pow__(self, y, z=None): # real signature unknown; restored from __doc__
    """ x.__pow__(y[, z]) <==> pow(x, y[, z]) """
    pass

  def __radd__(self, y): # real signature unknown; restored from __doc__
    """ x.__radd__(y) <==> y+x """
    pass

  def __rand__(self, y): # real signature unknown; restored from __doc__
    """ x.__rand__(y) <==> y&x """
    pass

  def __rdivmod__(self, y): # real signature unknown; restored from __doc__
    """ x.__rdivmod__(y) <==> divmod(y, x) """
    pass

  def __rdiv__(self, y): # real signature unknown; restored from __doc__
    """ x.__rdiv__(y) <==> y/x """
    pass

  def __repr__(self): # real signature unknown; restored from __doc__
    """ x.__repr__() <==> repr(x) """
    pass

  def __rfloordiv__(self, y): # real signature unknown; restored from __doc__
    """ x.__rfloordiv__(y) <==> y//x """
    pass

  def __rlshift__(self, y): # real signature unknown; restored from __doc__
    """ x.__rlshift__(y) <==> y<<x """
    pass

  def __rmod__(self, y): # real signature unknown; restored from __doc__
    """ x.__rmod__(y) <==> y%x """
    pass

  def __rmul__(self, y): # real signature unknown; restored from __doc__
    """ x.__rmul__(y) <==> y*x """
    pass

  def __ror__(self, y): # real signature unknown; restored from __doc__
    """ x.__ror__(y) <==> y|x """
    pass

  def __rpow__(self, x, z=None): # real signature unknown; restored from __doc__
    """ y.__rpow__(x[, z]) <==> pow(x, y[, z]) """
    pass

  def __rrshift__(self, y): # real signature unknown; restored from __doc__
    """ x.__rrshift__(y) <==> y>>x """
    pass

  def __rshift__(self, y): # real signature unknown; restored from __doc__
    """ x.__rshift__(y) <==> x>>y """
    pass

  def __rsub__(self, y): # real signature unknown; restored from __doc__
    """ x.__rsub__(y) <==> y-x """
    pass

  def __rtruediv__(self, y): # real signature unknown; restored from __doc__
    """ x.__rtruediv__(y) <==> y/x """
    pass

  def __rxor__(self, y): # real signature unknown; restored from __doc__
    """ x.__rxor__(y) <==> y^x """
    pass

  def __sizeof__(self, *args, **kwargs): # real signature unknown
    """ Returns size in memory, in bytes """
    pass

  def __str__(self): # real signature unknown; restored from __doc__
    """ x.__str__() <==> str(x) """
    pass

  def __sub__(self, y): # real signature unknown; restored from __doc__
    """ x.__sub__(y) <==> x-y """
    pass

  def __truediv__(self, y): # real signature unknown; restored from __doc__
    """ x.__truediv__(y) <==> x/y """
    pass

  def __trunc__(self, *args, **kwargs): # real signature unknown
    """ Truncating an Integral returns itself. """
    pass

  def __xor__(self, y): # real signature unknown; restored from __doc__
    """ x.__xor__(y) <==> x^y """
    pass

  denominator = property(lambda self: object(), lambda self, v: None, lambda self: None) # default
  """the denominator of a rational number in lowest terms"""

  imag = property(lambda self: object(), lambda self, v: None, lambda self: None) # default
  """the imaginary part of a complex number"""

  numerator = property(lambda self: object(), lambda self, v: None, lambda self: None) # default
  """the numerator of a rational number in lowest terms"""

  real = property(lambda self: object(), lambda self, v: None, lambda self: None) # default
  """the real part of a complex number"""

long

long

注:跟C語言不同,Python的長整數(shù)沒有指定位寬,即:Python沒有限制長整數(shù)數(shù)值的大小,但實(shí)際上由于機(jī)器內(nèi)存有限,我們使用的長整數(shù)數(shù)值不可能無限大。自從Python2.2起,如果整數(shù)發(fā)生溢出,Python會自動將整數(shù)數(shù)據(jù)轉(zhuǎn)換為長整數(shù),所以如今在長整數(shù)數(shù)據(jù)后面不加字母L也不會導(dǎo)致嚴(yán)重后果

三、浮點(diǎn)型
如:3.14、2.88

類型常用功能:

#浮點(diǎn)型功能與整形基本類似

class float(object):
  """
  float(x) -> floating point number
  
  Convert a string or number to a floating point number, if possible.
  """
  def as_integer_ratio(self):  
    """ 獲取改值的最簡比 """
    """
    float.as_integer_ratio() -> (int, int)

    Return a pair of integers, whose ratio is exactly equal to the original
    float and with a positive denominator.
    Raise OverflowError on infinities and a ValueError on NaNs.

    >>> (10.0).as_integer_ratio()
    (10, 1)
    >>> (0.0).as_integer_ratio()
    (0, 1)
    >>> (-.25).as_integer_ratio()
    (-1, 4)
    """
    pass

  def conjugate(self, *args, **kwargs): # real signature unknown
    """ Return self, the complex conjugate of any float. """
    pass

  def fromhex(self, string):  
    """ 將十六進(jìn)制字符串轉(zhuǎn)換成浮點(diǎn)型 """
    """
    float.fromhex(string) -> float
    
    Create a floating-point number from a hexadecimal string.
    >>> float.fromhex('0x1.ffffp10')
    2047.984375
    >>> float.fromhex('-0x1p-1074')
    -4.9406564584124654e-324
    """
    return 0.0

  def hex(self):  
    """ 返回當(dāng)前值的 16 進(jìn)制表示 """
    """
    float.hex() -> string
    
    Return a hexadecimal representation of a floating-point number.
    >>> (-0.1).hex()
    '-0x1.999999999999ap-4'
    >>> 3.14159.hex()
    '0x1.921f9f01b866ep+1'
    """
    return ""

  def is_integer(self, *args, **kwargs): # real signature unknown
    """ Return True if the float is an integer. """
    pass

  def __abs__(self):  
    """ x.__abs__() <==> abs(x) """
    pass

  def __add__(self, y):  
    """ x.__add__(y) <==> x+y """
    pass

  def __coerce__(self, y):  
    """ x.__coerce__(y) <==> coerce(x, y) """
    pass

  def __divmod__(self, y):  
    """ x.__divmod__(y) <==> divmod(x, y) """
    pass

  def __div__(self, y):  
    """ x.__div__(y) <==> x/y """
    pass

  def __eq__(self, y):  
    """ x.__eq__(y) <==> x==y """
    pass

  def __float__(self):  
    """ x.__float__() <==> float(x) """
    pass

  def __floordiv__(self, y):  
    """ x.__floordiv__(y) <==> x//y """
    pass

  def __format__(self, format_spec):  
    """
    float.__format__(format_spec) -> string
    
    Formats the float according to format_spec.
    """
    return ""

  def __getattribute__(self, name):  
    """ x.__getattribute__('name') <==> x.name """
    pass

  def __getformat__(self, typestr):  
    """
    float.__getformat__(typestr) -> string
    
    You probably don't want to use this function. It exists mainly to be
    used in Python's test suite.
    
    typestr must be 'double' or 'float'. This function returns whichever of
    'unknown', 'IEEE, big-endian' or 'IEEE, little-endian' best describes the
    format of floating point numbers used by the C type named by typestr.
    """
    return ""

  def __getnewargs__(self, *args, **kwargs): # real signature unknown
    pass

  def __ge__(self, y):  
    """ x.__ge__(y) <==> x>=y """
    pass

  def __gt__(self, y):  
    """ x.__gt__(y) <==> x>y """
    pass

  def __hash__(self):  
    """ x.__hash__() <==> hash(x) """
    pass

  def __init__(self, x):  
    pass

  def __int__(self):  
    """ x.__int__() <==> int(x) """
    pass

  def __le__(self, y):  
    """ x.__le__(y) <==> x<=y """
    pass

  def __long__(self):  
    """ x.__long__() <==> long(x) """
    pass

  def __lt__(self, y):  
    """ x.__lt__(y) <==> x<y """
    pass

  def __mod__(self, y):  
    """ x.__mod__(y) <==> x%y """
    pass

  def __mul__(self, y):  
    """ x.__mul__(y) <==> x*y """
    pass

  def __neg__(self):  
    """ x.__neg__() <==> -x """
    pass

  @staticmethod # known case of __new__
  def __new__(S, *more):  
    """ T.__new__(S, ...) -> a new object with type S, a subtype of T """
    pass

  def __ne__(self, y):  
    """ x.__ne__(y) <==> x!=y """
    pass

  def __nonzero__(self):  
    """ x.__nonzero__() <==> x != 0 """
    pass

  def __pos__(self):  
    """ x.__pos__() <==> +x """
    pass

  def __pow__(self, y, z=None):  
    """ x.__pow__(y[, z]) <==> pow(x, y[, z]) """
    pass

  def __radd__(self, y):  
    """ x.__radd__(y) <==> y+x """
    pass

  def __rdivmod__(self, y):  
    """ x.__rdivmod__(y) <==> divmod(y, x) """
    pass

  def __rdiv__(self, y):  
    """ x.__rdiv__(y) <==> y/x """
    pass

  def __repr__(self):  
    """ x.__repr__() <==> repr(x) """
    pass

  def __rfloordiv__(self, y):  
    """ x.__rfloordiv__(y) <==> y//x """
    pass

  def __rmod__(self, y):  
    """ x.__rmod__(y) <==> y%x """
    pass

  def __rmul__(self, y):  
    """ x.__rmul__(y) <==> y*x """
    pass

  def __rpow__(self, x, z=None):  
    """ y.__rpow__(x[, z]) <==> pow(x, y[, z]) """
    pass

  def __rsub__(self, y):  
    """ x.__rsub__(y) <==> y-x """
    pass

  def __rtruediv__(self, y):  
    """ x.__rtruediv__(y) <==> y/x """
    pass

  def __setformat__(self, typestr, fmt):  
    """
    float.__setformat__(typestr, fmt) -> None
    
    You probably don't want to use this function. It exists mainly to be
    used in Python's test suite.
    
    typestr must be 'double' or 'float'. fmt must be one of 'unknown',
    'IEEE, big-endian' or 'IEEE, little-endian', and in addition can only be
    one of the latter two if it appears to match the underlying C reality.
    
    Override the automatic determination of C-level floating point type.
    This affects how floats are converted to and from binary strings.
    """
    pass

  def __str__(self):  
    """ x.__str__() <==> str(x) """
    pass

  def __sub__(self, y):  
    """ x.__sub__(y) <==> x-y """
    pass

  def __truediv__(self, y):  
    """ x.__truediv__(y) <==> x/y """
    pass

  def __trunc__(self, *args, **kwargs): # real signature unknown
    """ Return the Integral closest to x between 0 and x. """
    pass

  imag = property(lambda self: object(), lambda self, v: None, lambda self: None) # default
  """the imaginary part of a complex number"""

  real = property(lambda self: object(), lambda self, v: None, lambda self: None) # default
  """the real part of a complex number"""

 float

float

四、字符串
如:'wupeiqi'、'alex'、'solo'

類型常用功能:

name = "my name is solo"
print(name.capitalize())      #首字母大寫
#My name is solo
print(name.count("l"))       #統(tǒng)計字符串出現(xiàn)某個字符的個數(shù)
#2
print(name.center(30,"-"))     #打印30個字符,不夠的-補(bǔ)齊
#--------my name is solo--------
print(name.ljust(30,"-"))      #打印30個字符,不夠的-補(bǔ)齊,字符串在左邊
#my name is solo----------------
print(name.endswith("solo"))     #判斷字符串是否以solo結(jié)尾
#True
print(name[name.find("na"):])    #find尋找na所在的索引下標(biāo) 字符串也可以切片
#name is solo
print("5.3".isdigit())       #判斷字符是否為整數(shù)
#False
print("a_1A".isidentifier())    #判斷是不是一個合法的標(biāo)識符(變量名)
#True
print("+".join(["1","2","3"]))   #把join后的內(nèi)容加入到前面字符串中,以+為分割符
#1+2+3
print("\nsolo".strip())       #去換行符
#solo
print("1+2+3+4".split("+"))    #以+為分隔符生成新的列表,默認(rèn)不寫為空格
#['1', '2', '3', '4']
name = "my name is {name} and i an {year} old"
print(name.format(name="solo",year=20)
#my name is solo and i an 20 old
print(name.format_map({"name":"solo","year":20}))      #很少用
#my name is solo and i an 20 old
p = str.maketrans("abcdefli","12345678")     #轉(zhuǎn)換 一一對應(yīng)
print("lianzhilei".translate(p))
#781nzh8758
class str(basestring):
  """
  str(object='') -> string
  
  Return a nice string representation of the object.
  If the argument is a string, the return value is the same object.
  """
  def capitalize(self): 
    """ 首字母變大寫 """
    """
    S.capitalize() -> string
    
    Return a copy of the string S with only its first character
    capitalized.
    """
    return ""

  def center(self, width, fillchar=None): 
    """ 內(nèi)容居中,width:總長度;fillchar:空白處填充內(nèi)容,默認(rèn)無 """
    """
    S.center(width[, fillchar]) -> string
    
    Return S centered in a string of length width. Padding is
    done using the specified fill character (default is a space)
    """
    return ""

  def count(self, sub, start=None, end=None): 
    """ 子序列個數(shù) """
    """
    S.count(sub[, start[, end]]) -> int
    
    Return the number of non-overlapping occurrences of substring sub in
    string S[start:end]. Optional arguments start and end are interpreted
    as in slice notation.
    """
    return 0

  def decode(self, encoding=None, errors=None): 
    """ 解碼 """
    """
    S.decode([encoding[,errors]]) -> object
    
    Decodes S using the codec registered for encoding. encoding defaults
    to the default encoding. errors may be given to set a different error
    handling scheme. Default is 'strict' meaning that encoding errors raise
    a UnicodeDecodeError. Other possible values are 'ignore' and 'replace'
    as well as any other name registered with codecs.register_error that is
    able to handle UnicodeDecodeErrors.
    """
    return object()

  def encode(self, encoding=None, errors=None): 
    """ 編碼,針對unicode """
    """
    S.encode([encoding[,errors]]) -> object
    
    Encodes S using the codec registered for encoding. encoding defaults
    to the default encoding. errors may be given to set a different error
    handling scheme. Default is 'strict' meaning that encoding errors raise
    a UnicodeEncodeError. Other possible values are 'ignore', 'replace' and
    'xmlcharrefreplace' as well as any other name registered with
    codecs.register_error that is able to handle UnicodeEncodeErrors.
    """
    return object()

  def endswith(self, suffix, start=None, end=None): 
    """ 是否以 xxx 結(jié)束 """
    """
    S.endswith(suffix[, start[, end]]) -> bool
    
    Return True if S ends with the specified suffix, False otherwise.
    With optional start, test S beginning at that position.
    With optional end, stop comparing S at that position.
    suffix can also be a tuple of strings to try.
    """
    return False

  def expandtabs(self, tabsize=None): 
    """ 將tab轉(zhuǎn)換成空格,默認(rèn)一個tab轉(zhuǎn)換成8個空格 """
    """
    S.expandtabs([tabsize]) -> string
    
    Return a copy of S where all tab characters are expanded using spaces.
    If tabsize is not given, a tab size of 8 characters is assumed.
    """
    return ""

  def find(self, sub, start=None, end=None): 
    """ 尋找子序列位置,如果沒找到,返回 -1 """
    """
    S.find(sub [,start [,end]]) -> int
    
    Return the lowest index in S where substring sub is found,
    such that sub is contained within S[start:end]. Optional
    arguments start and end are interpreted as in slice notation.
    
    Return -1 on failure.
    """
    return 0

  def format(*args, **kwargs): # known special case of str.format
    """ 字符串格式化,動態(tài)參數(shù),將函數(shù)式編程時細(xì)說 """
    """
    S.format(*args, **kwargs) -> string
    
    Return a formatted version of S, using substitutions from args and kwargs.
    The substitutions are identified by braces ('{' and '}').
    """
    pass

  def index(self, sub, start=None, end=None): 
    """ 子序列位置,如果沒找到,報錯 """
    S.index(sub [,start [,end]]) -> int
    
    Like S.find() but raise ValueError when the substring is not found.
    """
    return 0

  def isalnum(self): 
    """ 是否是字母和數(shù)字 """
    """
    S.isalnum() -> bool
    
    Return True if all characters in S are alphanumeric
    and there is at least one character in S, False otherwise.
    """
    return False

  def isalpha(self): 
    """ 是否是字母 """
    """
    S.isalpha() -> bool
    
    Return True if all characters in S are alphabetic
    and there is at least one character in S, False otherwise.
    """
    return False

  def isdigit(self): 
    """ 是否是數(shù)字 """
    """
    S.isdigit() -> bool
    
    Return True if all characters in S are digits
    and there is at least one character in S, False otherwise.
    """
    return False

  def islower(self): 
    """ 是否小寫 """
    """
    S.islower() -> bool
    
    Return True if all cased characters in S are lowercase and there is
    at least one cased character in S, False otherwise.
    """
    return False

  def isspace(self): 
    """
    S.isspace() -> bool
    
    Return True if all characters in S are whitespace
    and there is at least one character in S, False otherwise.
    """
    return False

  def istitle(self): 
    """
    S.istitle() -> bool
    
    Return True if S is a titlecased string and there is at least one
    character in S, i.e. uppercase characters may only follow uncased
    characters and lowercase characters only cased ones. Return False
    otherwise.
    """
    return False

  def isupper(self): 
    """
    S.isupper() -> bool
    
    Return True if all cased characters in S are uppercase and there is
    at least one cased character in S, False otherwise.
    """
    return False

  def join(self, iterable): 
    """ 連接 """
    """
    S.join(iterable) -> string
    
    Return a string which is the concatenation of the strings in the
    iterable. The separator between elements is S.
    """
    return ""

  def ljust(self, width, fillchar=None): 
    """ 內(nèi)容左對齊,右側(cè)填充 """
    """
    S.ljust(width[, fillchar]) -> string
    
    Return S left-justified in a string of length width. Padding is
    done using the specified fill character (default is a space).
    """
    return ""

  def lower(self): 
    """ 變小寫 """
    """
    S.lower() -> string
    
    Return a copy of the string S converted to lowercase.
    """
    return ""

  def lstrip(self, chars=None): 
    """ 移除左側(cè)空白 """
    """
    S.lstrip([chars]) -> string or unicode
    
    Return a copy of the string S with leading whitespace removed.
    If chars is given and not None, remove characters in chars instead.
    If chars is unicode, S will be converted to unicode before stripping
    """
    return ""

  def partition(self, sep): 
    """ 分割,前,中,后三部分 """
    """
    S.partition(sep) -> (head, sep, tail)
    
    Search for the separator sep in S, and return the part before it,
    the separator itself, and the part after it. If the separator is not
    found, return S and two empty strings.
    """
    pass

  def replace(self, old, new, count=None): 
    """ 替換 """
    """
    S.replace(old, new[, count]) -> string
    
    Return a copy of string S with all occurrences of substring
    old replaced by new. If the optional argument count is
    given, only the first count occurrences are replaced.
    """
    return ""

  def rfind(self, sub, start=None, end=None): 
    """
    S.rfind(sub [,start [,end]]) -> int
    
    Return the highest index in S where substring sub is found,
    such that sub is contained within S[start:end]. Optional
    arguments start and end are interpreted as in slice notation.
    
    Return -1 on failure.
    """
    return 0

  def rindex(self, sub, start=None, end=None): 
    """
    S.rindex(sub [,start [,end]]) -> int
    
    Like S.rfind() but raise ValueError when the substring is not found.
    """
    return 0

  def rjust(self, width, fillchar=None): 
    """
    S.rjust(width[, fillchar]) -> string
    
    Return S right-justified in a string of length width. Padding is
    done using the specified fill character (default is a space)
    """
    return ""

  def rpartition(self, sep): 
    """
    S.rpartition(sep) -> (head, sep, tail)
    
    Search for the separator sep in S, starting at the end of S, and return
    the part before it, the separator itself, and the part after it. If the
    separator is not found, return two empty strings and S.
    """
    pass

  def rsplit(self, sep=None, maxsplit=None): 
    """
    S.rsplit([sep [,maxsplit]]) -> list of strings
    
    Return a list of the words in the string S, using sep as the
    delimiter string, starting at the end of the string and working
    to the front. If maxsplit is given, at most maxsplit splits are
    done. If sep is not specified or is None, any whitespace string
    is a separator.
    """
    return []

  def rstrip(self, chars=None): 
    """
    S.rstrip([chars]) -> string or unicode
    
    Return a copy of the string S with trailing whitespace removed.
    If chars is given and not None, remove characters in chars instead.
    If chars is unicode, S will be converted to unicode before stripping
    """
    return ""

  def split(self, sep=None, maxsplit=None): 
    """ 分割, maxsplit最多分割幾次 """
    """
    S.split([sep [,maxsplit]]) -> list of strings
    
    Return a list of the words in the string S, using sep as the
    delimiter string. If maxsplit is given, at most maxsplit
    splits are done. If sep is not specified or is None, any
    whitespace string is a separator and empty strings are removed
    from the result.
    """
    return []

  def splitlines(self, keepends=False): 
    """ 根據(jù)換行分割 """
    """
    S.splitlines(keepends=False) -> list of strings
    
    Return a list of the lines in S, breaking at line boundaries.
    Line breaks are not included in the resulting list unless keepends
    is given and true.
    """
    return []

  def startswith(self, prefix, start=None, end=None): 
    """ 是否起始 """
    """
    S.startswith(prefix[, start[, end]]) -> bool
    
    Return True if S starts with the specified prefix, False otherwise.
    With optional start, test S beginning at that position.
    With optional end, stop comparing S at that position.
    prefix can also be a tuple of strings to try.
    """
    return False

  def strip(self, chars=None): 
    """ 移除兩段空白 """
    """
    S.strip([chars]) -> string or unicode
    
    Return a copy of the string S with leading and trailing
    whitespace removed.
    If chars is given and not None, remove characters in chars instead.
    If chars is unicode, S will be converted to unicode before stripping
    """
    return ""

  def swapcase(self): 
    """ 大寫變小寫,小寫變大寫 """
    """
    S.swapcase() -> string
    
    Return a copy of the string S with uppercase characters
    converted to lowercase and vice versa.
    """
    return ""

  def title(self): 
    """
    S.title() -> string
    
    Return a titlecased version of S, i.e. words start with uppercase
    characters, all remaining cased characters have lowercase.
    """
    return ""

  def translate(self, table, deletechars=None): 
    """
    轉(zhuǎn)換,需要先做一個對應(yīng)表,最后一個表示刪除字符集合
    intab = "aeiou"
    outtab = "12345"
    trantab = maketrans(intab, outtab)
    str = "this is string example....wow!!!"
    print str.translate(trantab, 'xm')
    """

    """
    S.translate(table [,deletechars]) -> string
    
    Return a copy of the string S, where all characters occurring
    in the optional argument deletechars are removed, and the
    remaining characters have been mapped through the given
    translation table, which must be a string of length 256 or None.
    If the table argument is None, no translation is applied and
    the operation simply removes the characters in deletechars.
    """
    return ""

  def upper(self): 
    """
    S.upper() -> string
    
    Return a copy of the string S converted to uppercase.
    """
    return ""

  def zfill(self, width): 
    """方法返回指定長度的字符串,原字符串右對齊,前面填充0。"""
    """
    S.zfill(width) -> string
    
    Pad a numeric string S with zeros on the left, to fill a field
    of the specified width. The string S is never truncated.
    """
    return ""

  def _formatter_field_name_split(self, *args, **kwargs): # real signature unknown
    pass

  def _formatter_parser(self, *args, **kwargs): # real signature unknown
    pass

  def __add__(self, y): 
    """ x.__add__(y) <==> x+y """
    pass

  def __contains__(self, y): 
    """ x.__contains__(y) <==> y in x """
    pass

  def __eq__(self, y): 
    """ x.__eq__(y) <==> x==y """
    pass

  def __format__(self, format_spec): 
    """
    S.__format__(format_spec) -> string
    
    Return a formatted version of S as described by format_spec.
    """
    return ""

  def __getattribute__(self, name): 
    """ x.__getattribute__('name') <==> x.name """
    pass

  def __getitem__(self, y): 
    """ x.__getitem__(y) <==> x[y] """
    pass

  def __getnewargs__(self, *args, **kwargs): # real signature unknown
    pass

  def __getslice__(self, i, j): 
    """
    x.__getslice__(i, j) <==> x[i:j]
          
          Use of negative indices is not supported.
    """
    pass

  def __ge__(self, y): 
    """ x.__ge__(y) <==> x>=y """
    pass

  def __gt__(self, y): 
    """ x.__gt__(y) <==> x>y """
    pass

  def __hash__(self): 
    """ x.__hash__() <==> hash(x) """
    pass

  def __init__(self, string=''): # known special case of str.__init__
    """
    str(object='') -> string
    
    Return a nice string representation of the object.
    If the argument is a string, the return value is the same object.
    # (copied from class doc)
    """
    pass

  def __len__(self): 
    """ x.__len__() <==> len(x) """
    pass

  def __le__(self, y): 
    """ x.__le__(y) <==> x<=y """
    pass

  def __lt__(self, y): 
    """ x.__lt__(y) <==> x<y """
    pass

  def __mod__(self, y): 
    """ x.__mod__(y) <==> x%y """
    pass

  def __mul__(self, n): 
    """ x.__mul__(n) <==> x*n """
    pass

  @staticmethod # known case of __new__
  def __new__(S, *more): 
    """ T.__new__(S, ...) -> a new object with type S, a subtype of T """
    pass

  def __ne__(self, y): 
    """ x.__ne__(y) <==> x!=y """
    pass

  def __repr__(self): 
    """ x.__repr__() <==> repr(x) """
    pass

  def __rmod__(self, y): 
    """ x.__rmod__(y) <==> y%x """
    pass

  def __rmul__(self, n): 
    """ x.__rmul__(n) <==> n*x """
    pass

  def __sizeof__(self): 
    """ S.__sizeof__() -> size of S in memory, in bytes """
    pass

  def __str__(self): 
    """ x.__str__() <==> str(x) """
    pass

str

str

五、列表


如:[11,22,33,44,55]、['wupeiqi', 'alex','solo']
1、創(chuàng)建列表:

#兩種創(chuàng)建方式
name_list = ['alex', 'seven', 'eric']
name_list = list(['alex', 'seven', 'eric'])

2、列表類常用功能:
① 切片

name_list = ["Alex","Tenglan","Eric","Rain","Tom","Amy"]
print(name_list[0:3])    #取下標(biāo)0至下標(biāo)3之間的元素,包括0,不包括3
#['Alex', 'Tenglan', 'Eric']
print(name_list[:3])    #:前什么都不寫,表示從0開始,效果跟上句一樣
#['Alex', 'Tenglan', 'Eric']
print(name_list[3:])    #:后什么不寫,表示取值到最后
#['Rain', 'Tom', 'Amy']
print(name_list[:])     #:前后都不寫,表示取值所有
#['Alex', 'Tenglan', 'Eric', 'Rain', 'Tom', 'Amy']
print(name_list[-3:-1])   #從-3開始到-1,包括-3,不包括-1
#['Rain', 'Tom']
print(name_list[1:-1])   #從1開始到-1,下標(biāo)有正有負(fù)時,正數(shù)在前負(fù)數(shù)在后
#['Tenglan', 'Eric', 'Rain', 'Tom']
print(name_list[::2])    #2表示,每個1個元素,就取一個
#['Alex', 'Eric', 'Tom']
#注:[-1:0] [0:0] [-1:2] 都是空

② 追加

name_list = ["Alex","Tenglan","Eric","Rain","Tom","Amy"]
name_list.append("new")     #append追加,加到最后,只能添加一個
print(name_list)
#['Alex', 'Tenglan', 'Eric', 'Rain', 'Tom', 'Amy', 'new']

③ 插入

name_list = ["Alex","Tenglan","Eric","Rain","Tom","Amy"]
name_list.insert(3,"new")     #insert插入,把"new"加到下標(biāo)3的位置
print(name_list)

④ 修改

name_list = ["Alex","Tenglan","Eric","Rain","Tom","Amy"]
name_list[2] = "solo"        #把下標(biāo)2的字符串換成solo
print(name_list)

⑤ 刪除

#3種刪除方式
name_list = ["Alex","Tenglan","Eric","Rain","Tom","Amy"]
del name_list[3]           #del刪除,指定要刪除的下標(biāo)
print(name_list)
#['Alex', 'Tenglan', 'Eric', 'Tom', 'Amy']
name_list.remove("Tenglan")     #remove刪除,指定要刪除的字符
print(name_list)
#['Alex', 'Eric', 'Tom', 'Amy']
name_list.pop()            #pop刪除,刪除列表最后一個值
print(name_list)
#['Alex', 'Eric', 'Tom']

⑥ 擴(kuò)展

name_list = ["Alex","Tenglan","Eric","Rain","Tom","Amy"]
age_list = [11,22,33]
name_list.extend(age_list)        #extend擴(kuò)展,把列表age_list添加到name_list列表
print(name_list)

⑦ 拷貝

name_list = ["Alex","Tenglan","Eric","Rain","Tom","Amy"]
copy_list = name_list.copy()        #copy拷貝,對列表進(jìn)行復(fù)制
print(copy_list)
#注:之后會整理深淺copy的詳細(xì)區(qū)分

⑧ 統(tǒng)計

name_list = ["Alex","Tenglan","Eric","Amy","Tom","Amy"]
print(name_list.count("Amy"))        #count統(tǒng)計,統(tǒng)計列表Amy的個數(shù)
#2

⑨ 排序和翻轉(zhuǎn)

name_list = ["Alex","Tenglan","Eric","Rain","Tom","Amy","1","2","3"]
name_list.sort()               #sort排序,對列表進(jìn)行排序
print(name_list)
#['1', '2', '3', 'Alex', 'Amy', 'Eric', 'Rain', 'Tenglan', 'Tom']
name_list.reverse()              #reverse翻轉(zhuǎn),對列表進(jìn)行翻轉(zhuǎn)
print(name_list)
#['Tom', 'Tenglan', 'Rain', 'Eric', 'Amy', 'Alex', '3', '2', '1']

⑩ 獲取下標(biāo)

name_list = ["Alex","Tenglan","Eric","Rain","Tom","Amy"]
print(name_list.index("Tenglan"))       #index索引,獲取字符的下標(biāo)
#1

六、元組

如:(11,22,33,44,55)、('wupeiqi', 'alex','lzl')

1、創(chuàng)建元組:

#5種創(chuàng)建方式
age = 11,22,33,44,55      #直接寫數(shù)字或者字符串,默認(rèn)創(chuàng)建類型元組 字符串類型用引號'solo'
#輸出: (11, 22, 33, 44, 55)  
age = (11,22,33,44,55)     #常見命名方式,()指定類型元組
#輸出: (11, 22, 33, 44, 55)
age = tuple((11,22,33,44,55))  #tuple 以類的方式創(chuàng)建(()) 雙括號 里面的()不可去掉
#輸出: (11, 22, 33, 44, 55)
age = tuple([11,22,33,44,55])  #同(()) 效果一樣 很少用 忘記它
#輸出: (11, 22, 33, 44, 55)
age = tuple({11,22,33,44,55})  #({})創(chuàng)建的元組,隨機(jī)排列 沒卵用
#輸出: (33, 11, 44, 22, 55)

2、元組類常用功能:

##count        #統(tǒng)計元組字符出現(xiàn)的次數(shù)   
name = ('wupeiqi', 'alex','solo')
print(name.count('alex'))       
# 1
##index       #查看字符串所在的索引位置
name = ('wupeiqi', 'alex','solo')
print(name.index('solo'))        
# solo

七、字典 無序


如:{'name': 'wupeiqi', 'age': 18} 、{'host': 'solo.solo.solo.solo', 'port': 80}
注:字典一種key:value 的數(shù)據(jù)類型,也稱鍵值對。字典dict是無序的,key值必須是唯一的,不能有重復(fù)。循環(huán)時,默認(rèn)循環(huán)的是key
 1、創(chuàng)建字典

#兩種創(chuàng)建方式:
info_dic = {'stu1101': "TengLan Wu",'stu1102': "LongZe Luola",'stu1103': "XiaoZe Maliya",}
print(info_dic)
#{'stu1102': 'LongZe Luola', 'stu1101': 'TengLan Wu', 'stu1103': 'XiaoZe Maliya'}
info_dic = dict({'stu1101': "TengLan Wu",'stu1102': "LongZe Luola",'stu1103': "XiaoZe Maliya",})
print(info_dic)
#{'stu1102': 'LongZe Luola', 'stu1101': 'TengLan Wu', 'stu1103': 'XiaoZe Maliya'}

2、字典類常用功能:

① 增加

info_dic = {'stu1101': "TengLan Wu",'stu1102': "LongZe Luola",'stu1103': "XiaoZe Maliya",}
info_dic['stu1104'] = "JingKong Cang"      #增加
print(info_dic)

② 修改

info_dic = {'stu1101': "TengLan Wu",'stu1102': "LongZe Luola",'stu1103': "XiaoZe Maliya",}
info_dic["stu1101"] = "Jingkong Cang"     #有相應(yīng)的key時為修改,沒有為增加
print(info_dic)

 

③ 刪除

#3種刪除方式
info_dic = {'stu1101': "TengLan Wu",'stu1102': "LongZe Luola",'stu1103': "XiaoZe Maliya",}
info_dic.pop('stu1101')            #pop刪除,指定刪除的key
print(info_dic)
#{'stu1103': 'XiaoZe Maliya', 'stu1102': 'LongZe Luola'}
del info_dic['stu1102']           #del刪除,指定刪除的key
print(info_dic)
#{'stu1103': 'XiaoZe Maliya'}
info_dic = {'stu1101': "TengLan Wu",'stu1102': "LongZe Luola",'stu1103': "XiaoZe Maliya",}
info_dic.popitem()               #隨機(jī)刪除,沒卵用
print(info_dic)
#{'stu1101': 'TengLan Wu', 'stu1103': 'XiaoZe Maliya'}

 

④ 查找value值

info_dic = {'stu1101': "TengLan Wu",'stu1102': "LongZe Luola",'stu1103': "XiaoZe Maliya",}
print(info_dic.get('stu1102'))   #get查找,通過key查找value值
#LongZe Luola
print(info_dic['stu1102'])     #通過key直接查找,但是如果輸入查找的key不存在的話,就會報錯,get則不會
#LongZe Luola

 

⑤ 字典多級嵌套

  "歐美":{
    "www.youporn.com": ["很多免費(fèi)的,世界最大的","質(zhì)量一般"],
    "www.pornhub.com": ["很多免費(fèi)的,也很大","質(zhì)量比yourporn高點(diǎn)"],
    "letmedothistoyou.com": ["多是自拍,高質(zhì)量圖片很多","資源不多,更新慢"],
    "x-art.com":["質(zhì)量很高,真的很高","全部收費(fèi),屌比請繞過"]
  },
  "日韓":{
    "tokyo-hot":["質(zhì)量怎樣不清楚,個人已經(jīng)不喜歡日韓范了","聽說是收費(fèi)的"]
  },
  "大陸":{
    "1024":["全部免費(fèi),真好,好人一生平安","服務(wù)器在國外,慢"]
  }
}
 
av_catalog["大陸"]["1024"][1] += ",可以用爬蟲爬下來"
print(av_catalog["大陸"]["1024"])
#['全部免費(fèi),真好,好人一生平安', '服務(wù)器在國外,慢,可以用爬蟲爬下來']

⑥ 循環(huán)

info_dic = {'stu1101': "TengLan Wu",'stu1102': "LongZe Luola",'stu1103': "XiaoZe Maliya",}
for stu_nu in info_dic:
  print(stu_nu,info_dic[stu_nu])    #循環(huán)默認(rèn)提取的是key
#stu1103 XiaoZe Maliya
#stu1101 TengLan Wu
#stu1102 LongZe Luola
for k,v in info_dic.items():       #先把dict生成list,數(shù)據(jù)量大的時候費(fèi)時,不建議使用
  print(k,v)
#stu1103 XiaoZe Maliya
#stu1101 TengLan Wu
#stu1102 LongZe Luola

八、集合
如:{'solo', 33, 'alex', 22, 'eric', 'wupeiqi', 11}
注:集合是一個無序的,不重復(fù)的數(shù)據(jù)組合。去重性,把一個列表變成集合,就自動去重了。關(guān)系測試,測試兩組數(shù)據(jù)之前的交集、差集、并集
1、創(chuàng)建集合

 

#標(biāo)準(zhǔn)創(chuàng)建方式
info_set = set(["alex","wupeiqi","eric","solo",11,22,33])
print(info_set,type(info_set))
#{33, 11, 'wupeiqi', 'solo', 'alex', 'eric', 22} <class 'set'>

2、集合類常用功能
① 添加

#添加的兩種方式
set_1 = set(["alex","wupeiqi","eric","solo"])
set_1.add(11)             #add只能添加一個元素
print(set_1)
#{'alex', 'solo', 'eric', 11, 'wupeiqi'}
set_1 = set(["alex","wupeiqi","eric","solo"])
set_1.update([11,22,33])
print(set_1)              #update可以添加多個元素
#{33, 11, 'alex', 'wupeiqi', 'eric', 22, 'solo'}

② 刪除

#刪除的三種方式
set_1 = set(["alex","wupeiqi","eric","solo",11,22,33])
set_1.remove("alex")          #remove 刪除指定元素
print(set_1)
#{'eric', 33, 'solo', 11, 22, 'wupeiqi'}
set_1.pop()               #pop 隨機(jī)刪除元素
print(set_1)
#{33, 'wupeiqi', 11, 22, 'solo'}
set_1.discard("solo")          #discard 刪除指定元素,與remove區(qū)別在于,如果元素不存在也不會報錯
set_1.discard(55)
print(set_1)
#{33, 'wupeiqi', 11, 22}

3、集合關(guān)系測試
① 交集

set_1 = set(["alex","wupeiqi","eric","solo",11,22,33])
set_2 = set([11,22,33,44,55,66])
print(set_1.intersection(set_2))      #intersection 取兩個set的交集 set_1和set_2可以互換位置
#{33, 11, 22}

② 并集

set_1 = set(["alex","wupeiqi","eric","solo",11,22,33])
set_2 = set([11,22,33,44,55,66])
print(set_1.union(set_2))           #union 取兩個set集合的并集 set_1和set_2可以互換位置
#{33, 66, 11, 44, 'eric', 55, 'solo', 22, 'wupeiqi', 'alex'}

③ 差集

set_1 = set(["alex","wupeiqi","eric","solo",11,22,33])
set_2 = set([11,22,33,44,55,66])
print(set_1.difference(set_2))         #difference 取兩個set集合的差集 set_1有但是set_2沒有的集合
#{'solo', 'eric', 'wupeiqi', 'alex'}

④ 子集、父集

set_1 = set(["alex","wupeiqi","eric","solo",11,22,33])
set_2 = set([11,22,33,44,55,66])
set_3 = set([11,22,33])
print(set_1.issubset(set_2))           #issubset 子集
#False
print(set_1.issuperset(set_3))          #issuperset 父集
#True

⑤ 對稱差集

set_1 = set(["alex","wupeiqi","eric","solo",11,22,33])
set_2 = set([11,22,33,44,55,66])
print(set_1.symmetric_difference(set_2))      #symmetric_difference 對稱差集=兩個集合并集減去合集
#{66, 'solo', 'eric', 'alex', 55, 'wupeiqi', 44}

⑥ 運(yùn)算符做關(guān)系測試

set_1 = set(["alex","wupeiqi","eric","solo",11,22,33])
set_2 = set([11,22,33,44,55,66])
set_union = set_1 | set_2      # 并集
set_intersection = set_1 & set_2  # 交集
set_difference = set_1 - set_2   # 差集
set_symmetric_difference = set_1 ^ set_2 # 對稱差集

六、模塊初識

Python有大量的模塊,從而使得開發(fā)Python程序非常簡潔。類庫有包括三中:
① 、Python內(nèi)部提供的模塊
②、業(yè)內(nèi)開源的模塊
③、程序員自己開發(fā)的模塊:Python腳本的名字不要與模塊名相同

1、sys模塊(系統(tǒng)內(nèi)置)
① sys.argv 用來捕獲執(zhí)行python腳本時傳入的參數(shù)
② sys.stdin 標(biāo)準(zhǔn)信息輸入
③ sys.stdout 標(biāo)準(zhǔn)定向輸出
④ sys.stdout.flush 強(qiáng)制刷新標(biāo)準(zhǔn)輸出緩存

import time
import sys
for i in range(5):
  print(i),
  sys.stdout.flush()
  time.sleep(1)
# 這樣設(shè)計是為了打印一個數(shù)每秒五秒鐘,但如果您運(yùn)行它,因為它是現(xiàn)在(取決于您的默認(rèn)系統(tǒng)緩沖),
# 你可能看不到任何輸出 CodeGo.net,直到再一次全部,你會看到0 1 2 3 4打印到屏幕上。
# 這是輸出被緩沖,除非你sys.stdout之后每print你不會看到從輸出中取出sys.stdout.flush()網(wǎng)上看到的差別

2、os模塊(與系統(tǒng)進(jìn)行交互)
① os.dir、os.popen調(diào)用當(dāng)前系統(tǒng)命令

3、platform模塊(識別當(dāng)前運(yùn)行的系統(tǒng))

七、運(yùn)算符
1、算數(shù)運(yùn)算:

2、比較運(yùn)算:

3、賦值運(yùn)算:

4、邏輯運(yùn)算:

5、成員運(yùn)算:

6、身份運(yùn)算:

7、位運(yùn)算:

8、運(yùn)算符優(yōu)先級:

八、深淺拷貝剖析
1、對象賦值(創(chuàng)建列表變量Alex,變量包含子列表,通過變量Alex給變量solo賦值,然后對變量Alex的元素進(jìn)行修改,此時solo會有什么變化呢?)

import copy           #import調(diào)用copy模塊
 
Alex = ["Alex", 28, ["Python", "C#", "JavaScript"]]
solo = Alex            #直接賦值
 
#  修改前打印
print(id(Alex))
print(Alex)
print([id(adr) for adr in Alex])
# 輸出: 7316664
#    ['Alex', 28, ['Python', 'C#', 'JavaScript']]
#    [2775776, 1398430400, 7318024]
print(id(solo))
print(solo)
print([id(adr) for adr in solo])
# 輸出: 7316664
#    ['Alex', 28, ['Python', 'C#', 'JavaScript']]
#    [2775776, 1398430400, 7318024]
 
#  對變量進(jìn)行修改
Alex[0]='Mr.Wu'
Alex[2].append('CSS')
print(id(Alex))
print(Alex)
print([id(adr) for adr in Alex])
# 輸出: 7316664
#    ['Mr.Wu', 28, ['Python', 'C#', 'JavaScript', 'CSS']]
#    [5170528, 1398430400, 7318024]
print(id(solo))
print(solo)
print([id(adr) for adr in solo])
# 輸出: 7316664
#    ['Mr.Wu', 28, ['Python', 'C#', 'JavaScript', 'CSS']]
#    [5170528, 1398430400, 7318024]

初始條件: Alex = ["Alex", 28, ["Python", "C#", "JavaScript"]]
對象賦值: solo = Alex           #直接賦值
對象賦值結(jié)果:solo = ["Alex", 28, ["Python", "C#", "JavaScript"]]
對象賦值時是進(jìn)行對象引用(內(nèi)存地址)的傳遞,被賦值的變量并沒有開辟新內(nèi)存,兩個變量共用一個內(nèi)存地址

修改對象賦值:solo = ['Mr.Wu', 28, ['Python', 'C#', 'JavaScript', 'CSS']]
str是不可變類型,所以當(dāng)修改元素Alex為Mr.Wu時,內(nèi)存地址發(fā)生改變;list是可變類型,元素['Python', 'C#', 'JavaScript', 'CSS']修改完后,內(nèi)存地址沒有改變

2、淺拷貝(創(chuàng)建列表變量Alex,變量包含子列表,通過copy模塊的淺拷貝函數(shù)copy()對變量Alex進(jìn)行拷貝,當(dāng)對Alex進(jìn)行操作時,此時solo會如何變化?)

import copy           #import調(diào)用copy模塊
Alex = ["Alex", 28, ["Python", "C#", "JavaScript"]]
solo = copy.copy(Alex)            #通過copy模塊里面的淺拷貝函數(shù)copy()
#  修改前打印
print(id(Alex))
print(Alex)
print([id(adr) for adr in Alex])
# 輸出: 10462472
#    ['Alex', 28, ['Python', 'C#', 'JavaScript']]
#    [5462752, 1359960768, 10463232]
print(id(solo))
print(solo)
print([id(adr) for adr in solo])
# 輸出: 10201848
#    ['Alex', 28, ['Python', 'C#', 'JavaScript']]
#    [5462752, 1359960768, 10463232]
#  對變量進(jìn)行修改
Alex[0]='Mr.Wu'
Alex[2].append('CSS')
print(id(Alex))
print(Alex)
print([id(adr) for adr in Alex])
# 輸出: 10462472
#    ['Mr.Wu', 28, ['Python', 'C#', 'JavaScript', 'CSS']]
#    [10151264, 1359960768, 10463232]
print(id(solo))
print(solo)
print([id(adr) for adr in solo])
# 輸出: 10201848
#    ['Alex', 28, ['Python', 'C#', 'JavaScript', 'CSS']]
#    [5462752, 1359960768, 10463232]

初始條件: Alex = ["Alex", 28, ["Python", "C#", "JavaScript"]]
淺拷貝: solo = copy.copy(Alex)         #通過copy模塊里面的淺拷貝函數(shù)copy()
淺拷貝結(jié)果: solo = ["Alex", 28, ["Python", "C#", "JavaScript"]]
淺拷貝時變量solo新建了一塊內(nèi)存(10201848),此內(nèi)存記錄了list中元素的地址;對于list中的元素,淺拷貝會使用原始元素的引用(內(nèi)存地址)

修改淺拷貝: solo = ['Mr.Wu', 28, ['Python', 'C#', 'JavaScript', 'CSS']]
str是不可變類型,所以當(dāng)修改元素Alex為Mr.Wu時,內(nèi)存地址發(fā)生改變;list是可變類型,元素['Python', 'C#', 'JavaScript', 'CSS']修改完后,內(nèi)存地址沒有改變

3、深拷貝(創(chuàng)建列表變量Alex,變量包含子列表,通過copy模塊的深拷貝函數(shù)deepcopy()對變量Alex進(jìn)行拷貝,當(dāng)對Alex進(jìn)行操作時,此時solo會如何變化?)

#!/usr/bin/env python
# -*- coding:utf-8 -*-
#-Author-Lian
#  深拷貝
import copy           #import調(diào)用copy模塊
 
Alex = ["Alex", 28, ["Python", "C#", "JavaScript"]]
solo = copy.deepcopy(Alex)            #通過copy模塊里面的深拷貝函數(shù)deepcopy()
 
#  修改前打印
print(id(Alex))
print(Alex)
print([id(adr) for adr in Alex])
# 輸出: 6202712
#    ['Alex', 28, ['Python', 'C#', 'JavaScript']]
#    [4086496, 1363237568, 6203472]
print(id(solo))
print(solo)
print([id(adr) for adr in solo])
# 輸出: 6203032
#    ['Alex', 28, ['Python', 'C#', 'JavaScript']]
#    [4086496, 1363237568, 6203512]
 
#  對變量進(jìn)行修改
Alex[0]='Mr.Wu'
Alex[2].append('CSS')
print(id(Alex))
print(Alex)
print([id(adr) for adr in Alex])
# 輸出: 6202712
#    ['Mr.Wu', 28, ['Python', 'C#', 'JavaScript', 'CSS']]
#    [5236064, 1363237568, 6203472]
print(id(solo))
print(solo)
print([id(adr) for adr in solo])
# 輸出: 6203032
#    ['Alex', 28, ['Python', 'C#', 'JavaScript']]
#    [4086496, 1363237568, 6203512]

初始條件: Alex = ["Alex", 28, ["Python", "C#", "JavaScript"]]
深拷貝: solo = copy.deepcopy(Alex) #通過copy模塊里面的深拷貝函數(shù)deepcopy()
深拷貝結(jié)果: solo = ["Alex", 28, ["Python", "C#", "JavaScript"]]
深拷貝時變量solo新建了一塊內(nèi)存(10201848),此內(nèi)存記錄了list中元素的地址;但是,對于list中第三個元素(['Python', 'C#', 'JavaScript'])重新生成了一個地址(6203512),此時兩個變量的第三個元素的內(nèi)存引用地址不同

修改深拷貝: solo = ['Mr.Wu', 28, ['Python', 'C#', 'JavaScript', 'CSS']]
str是不可變類型,所以當(dāng)修改元素Alex為Mr.Wu時,內(nèi)存地址發(fā)生改變;list是可變類型,元素['Python', 'C#', 'JavaScript', 'CSS']修改完后,內(nèi)存地址沒有改變,但是Alex和solo在第三個元素引用的本就不同

4、對于拷貝有一些特殊情況
(1)對于非容器類型(如數(shù)字、字符串、和其他'原子'類型的對象)沒有拷貝這一說
(2)也就是說,對于這些類型,"obj is copy.copy(obj)" 、"obj is copy.deepcopy(obj)"
(3)如果元祖變量只包含原子類型對象,則不能深拷貝
①為什么要拷貝?
答:當(dāng)進(jìn)行修改時,想要保留原來的數(shù)據(jù)和修改后的數(shù)據(jù)
②數(shù)字字符串 和 集合 在修改時的差異? (深淺拷貝不同的終極原因)
答:在修改數(shù)據(jù)時:
               數(shù)字字符串:在內(nèi)存中新建一份數(shù)據(jù)
               集合:修改內(nèi)存中的同一份數(shù)據(jù)
③對于集合,如何保留其修改前和修改后的數(shù)據(jù)?
答:在內(nèi)存中拷貝一份
④對于集合,如何拷貝其n層元素同時拷貝?
答:深拷貝

 

九、文件操作

(1)打開文件: 文件句柄 = file('文件路徑', '模式')
python中打開文件有兩種方式,即:open(...) 和 file(...) ,本質(zhì)上前者在內(nèi)部會調(diào)用后者來進(jìn)行文件操作,推薦使用 open。
1、打開文件的模式:
  r, 只讀模式【默認(rèn)】
  w,只寫模式【不可讀;不存在則創(chuàng)建;存在則刪除內(nèi)容;】
  a, 追加模式【不可讀;不存在則創(chuàng)建;存在則只追加內(nèi)容;】
2、"+" 同時讀寫某個文件:
  r+,可讀寫文件?!究勺x;可寫;可追加】
  w+,寫讀
  a+,追加讀

總結(jié)1:r+模式下,如果在.write()進(jìn)行寫入內(nèi)容前,有print()輸出,則要寫的內(nèi)容會從文件尾部開始寫入,使用的是讀、追加模式;如果在.write()進(jìn)行寫入內(nèi)容前,是seek()移動光標(biāo),則要寫的內(nèi)容會從移動到的光標(biāo)開始進(jìn)行寫入,會把原來的內(nèi)容覆蓋掉,而不是整體后移,這點(diǎn)要記?。蝗绻?write()進(jìn)行寫入內(nèi)容前,既沒有print()也沒有seek()光標(biāo)移動,這種情況之前想的的情況,就是r+讀寫模式能先寫后讀嗎?r+模式下默認(rèn)光標(biāo)在文件的首部,此時會直接從文件開頭進(jìn)行寫入,效果等同于seek(0)。關(guān)于最后一點(diǎn),參考a+模式。
總結(jié)2:讀寫模式一定要先寫后讀嗎?能不能先讀后寫? 如果先讀的話,由于用的是w+模式打開的文件,打開后會清空原文件內(nèi)容,所有讀取的到東西是空的。另W+模式后期用的很少,了解即可,包括a+追加讀這種模式;另w+模式下,光標(biāo)會跟隨文件寫入移到到文件末尾,不用seek移到光標(biāo)的話,打印內(nèi)容為空
注:w+模式下,關(guān)于.write()跟seek()和print()的關(guān)系與r+模式下是一樣一樣的。w+打開文件后先清空,然后追加寫,如果.write()前有seek()的話會從光標(biāo)位置覆蓋寫。
總結(jié)3:通過上面的程序可以得出,a+模式下光標(biāo)位置為文件末尾,如果要print()的話要結(jié)合seek()進(jìn)行使用;另外與r+、w+不同的是,.write()與seek()沒有關(guān)系,只能寫內(nèi)容到文件末尾,一直都是追加模式!

小結(jié)

3、"U"表示在讀取時,可以將 \r \n \r\n自動轉(zhuǎn)換成 \n (與 r 或 r+ 模式同使用)
  rU
  r+U
4、"b"表示處理二進(jìn)制文件(如:FTP發(fā)送上傳ISO鏡像文件,linux可忽略,windows處理二進(jìn)制文件時需標(biāo)注)
  rb 二進(jìn)制讀
  wb 二進(jìn)制寫(ab也一樣)
  ab
(2)文件操作常用功能:
1、read()、readline()、readlines()的區(qū)別
  print(info_file.read()) #read參數(shù),讀取文件所有內(nèi)容
  print(info_file.readline()) #readline,只讀取文章中的一行內(nèi)容
  print(info_file.readlines()) #readlines,把文章內(nèi)容以換行符分割,并生成list格式,數(shù)據(jù)量大的話不建議使用
2、seek、tell光標(biāo)
  data = info_file.read() #默認(rèn)光標(biāo)在起始位置,.read()讀取完后,光標(biāo)停留到文件末尾
  print(info_file.tell()) #tell 獲取當(dāng)前的光標(biāo)位
  info_file.seek(0) #seek 移動光標(biāo)到文件首部
3、文件循環(huán)
  for index,line in enumerate(info_file.readlines()): #先把文件內(nèi)容以行為分割生成列表,數(shù)據(jù)量大不能用
  for line in info_file: #建議使用方法,每讀取一行,內(nèi)存會把之前的空間清空,不會占用太多內(nèi)存
4、flush 刷新
  sys.stdout.flush() #flush 強(qiáng)制刷新緩存到內(nèi)存的數(shù)據(jù)寫入硬盤
5、truncate 截斷
  truncate跟光標(biāo)位置無關(guān),從文件首部開始截取字符;如果是truncate(0)會把文件清空
6、with 語句
  為了避免打開文件后忘記關(guān)閉,可以通過管理上下文,即:
    with open('log','r') as f:
    ...
如此方式,當(dāng)with代碼塊執(zhí)行完畢時,內(nèi)部會自動關(guān)閉并釋放文件資源。在Python 2.7 后,with又支持同時對多個文件的上下文進(jìn)行管理,即:
    with open('log1') as obj1, open('log2') as obj2:
    pass 
(3)文件修改方式:
1、把文件讀取到內(nèi)存當(dāng)中,對內(nèi)存進(jìn)行修改,把修改后的內(nèi)容寫入到原文件(舊內(nèi)容被清空)
2、如果在硬盤上直接寫,會進(jìn)行覆蓋,硬盤上不能進(jìn)行插入,原來的內(nèi)容不會整體后移,而是直接覆蓋掉
3、把文件讀取到內(nèi)存當(dāng)中,對內(nèi)存進(jìn)行修改,把修改的內(nèi)容另存為新的文件(舊文件保留)
 ?、?另存方式
 ?、?r+模式
  ③ a+模式

十、函數(shù)

①格式

def 函數(shù)名(參數(shù)):
      ....
      函數(shù)體
      ....
      return 返回值
  函數(shù)名()

②形參:  def func(name): // name 叫做函數(shù)func的形式參數(shù),簡稱:形參
③實(shí)參:  func("solo") // 'solo' 叫做函數(shù)func的實(shí)際參數(shù),簡稱:實(shí)參
④默認(rèn)參數(shù): def stu_register(name,age,course,country="CN") // 位置參數(shù)
⑤關(guān)鍵參數(shù): stu_register(age=22,name='lzl',course="python")  // 關(guān)鍵參數(shù)必須放在位置參數(shù)之后
⑥動態(tài)參數(shù)/非固定參數(shù)(*args 和 **kwargs):

(1)*args:*args會把多傳入的實(shí)參變成一個元組的類型;即使傳入的是list類型也會變成元組,成為元組中的一個元素;另函數(shù)中有*args與其他形參的時候,*args一定要寫到其 他形參的后面,否則傳入的實(shí)參都會被傳入到*args當(dāng)中打印成元組;還有如果沒有多出傳入的實(shí)參即*args沒有值的時候,*args為空,不會報錯。
(2)**kwargs:**kwargs會把多出的a=b這種類型的實(shí)參打印成字典的類型(要區(qū)分開與關(guān)鍵參數(shù)的區(qū)別,關(guān)鍵參數(shù)的實(shí)參有對應(yīng)的形參),被當(dāng)成多余的實(shí)參傳入到了*args里面,所以**kwargs的值才為空,分別用*inf_list和**info_dict的方式傳入到*args、**kwargs當(dāng)中(stu_register("lzl",*info_list,**info_dict) //傳入列表和字典)
總結(jié):*args必須放到**kwargs前面(規(guī)定);位置參數(shù)一定要放到關(guān)鍵參數(shù)之前(規(guī)定);默認(rèn)參數(shù)不能跟*args、**kwargs一塊存在(會報錯)。

⑦return 返回值: 如果不執(zhí)行return,函數(shù)的默認(rèn)返回值為None;當(dāng)函數(shù)執(zhí)行到return時,函數(shù)結(jié)束執(zhí)行
⑧局部變量: name = "Alex Li" #定義變量name

def change_name(name):
name = "金角大王,一個有Tesla的男人"  #函數(shù)內(nèi)部更改變量
函數(shù)內(nèi)部對變量進(jìn)行更改后,生效范圍僅限于函數(shù)內(nèi)部,對外部變量沒有影響,這種變量稱為局部變量;函數(shù)內(nèi)部也可以讓變量全局生效,需要加參數(shù)global,這種情況很少用。

⑨遞歸函數(shù): 如果一個函數(shù)在內(nèi)部調(diào)用自身本身,這個函數(shù)就是遞歸函數(shù)
條件: 有結(jié)束條件、更深一層遞歸規(guī)模比上次遞歸有所減少、效率不高,遞歸層次過多會導(dǎo)致棧溢出

寫一個遞歸:
       def func(n1,n2):    #獲取斐波那契數(shù)列100之前的數(shù)字
         if n1 > 100:
           return
         print(n1)
         n3 = n1 + n2
         func(n2,n3)
       func(0,1)

⑩匿名函數(shù):不需要顯式的指定函數(shù)

#普通函數(shù)        #換成匿名函數(shù)
def calc(n):      calc = lambda n:n**n
return n**n     print(calc(10)
print(calc(10))

⑪高階函數(shù): 變量可以指向函數(shù),函數(shù)的參數(shù)能接收變量,那么一個函數(shù)就可以接收另一個函數(shù)作為參數(shù),這種函數(shù)就稱之為高階函數(shù)。

def add(x,y,f):
return f(x) + f(y)
res = add(3,-6,abs)
print(res)

⑫內(nèi)置函數(shù)

⑬函數(shù)的調(diào)用順序:被調(diào)用函數(shù)要在執(zhí)行之前被定義

#函數(shù)錯誤的調(diào)用方式
def func():           #定義函數(shù)func()
  print("in the func")
  foo()            #調(diào)用函數(shù)foo()
func()             #執(zhí)行函數(shù)func()
def foo():           #定義函數(shù)foo()
  print("in the foo")

#函數(shù)正確的調(diào)用方式
def func():           #定義函數(shù)func()
  print("in the func")
  foo()            #調(diào)用函數(shù)foo()
def foo():           #定義函數(shù)foo()
  print("in the foo")
func()             #執(zhí)行函數(shù)func()

⑭高階函數(shù):1、某一函數(shù)當(dāng)做參數(shù)傳入另一個函數(shù)中。2、函數(shù)的返回值包含一個或多個函數(shù)

⑮內(nèi)嵌函數(shù):在一個函數(shù)體內(nèi)創(chuàng)建另外一個函數(shù)(內(nèi)嵌函數(shù)中定義的函數(shù)在全局中是無法直接執(zhí)行的)

⑯裝飾器:本質(zhì)是函數(shù)(裝飾其他函數(shù)),為其他函數(shù)添加附加功能的。
遵循原則: 1.不能修改被裝飾函數(shù)的源代碼 2.不能修改被裝飾函數(shù)的調(diào)用方式
組成:裝飾器由高階函數(shù)+內(nèi)嵌函數(shù)組成

⑰生成器:調(diào)用時才會生成相應(yīng)數(shù)據(jù)的機(jī)制,稱為生成器:generator

應(yīng)用:可通過yield實(shí)現(xiàn)在單線程的情況下實(shí)現(xiàn)并發(fā)運(yùn)算的效果(協(xié)程)

#!/usr/bin/env python
# -*- coding:utf-8 -*-
#-Author-solo
import time
def consumer(name):
  print("%s 準(zhǔn)備吃包子啦!" %name)
  while True:
    baozi = yield      #yield的作用:保存當(dāng)前狀態(tài)并返回
 
    print("包子[%s]來了,被[%s]吃了!" %(baozi,name))
def producer(name):
  c = consumer('A')      
  c2 = consumer('B')    
  c.__next__()        #c.__next__()等同于next(c)
  c2.__next__()        #next()作用:調(diào)用yield,不給yield傳值
  print("老子開始準(zhǔn)備做包子啦!")
  for i in range(10):
    time.sleep(1)
    print("%s做了2個包子!"%(name))
    c.send(i)        #send()作用:調(diào)用yield,給yield傳值
    c2.send(i)
producer("solo")

協(xié)程

 

可迭代對象:可以直接作用于for循環(huán)的對象:Iterable
可以直接作用于for循環(huán)的數(shù)據(jù)類型有:1、集合數(shù)據(jù)類型,如list、tuple、dict、set、str等;2、生成器,包括generator和帶yield的generator function;
可以用isinstance()去判斷一個對象是否是Iterable對象

from collections import Iterable
print(isinstance([], Iterable))
# True

迭代器:可以被next()函數(shù)調(diào)用并不斷返回下一個值的對象稱為迭代器:Iterator。
用isinstance()判斷一個對象是否是Iterator對象

from collections import Iterator
print(isinstance([], Iterator))
# True
小結(jié):
1、凡是可作用于for循環(huán)的對象都是Iterable類型;
2、凡是可作用于next()函數(shù)的對象都是Iterator類型,它們表示一個惰性計算的序列;
3、集合數(shù)據(jù)類型如list、dict、str等是Iterable但不是Iterator,不過可以通過iter()函數(shù)獲得一個Iterator對象;
4、Python的for循環(huán)本質(zhì)上就是通過不斷調(diào)用next()函數(shù)實(shí)現(xiàn)的
for x in [1, 2, 3, 4, 5]:
pass
首先獲得Iterator對象:
it = iter([1, 2, 3, 4, 5])
# 循環(huán):
while True:
  try:
    # 獲得下一個值:
    x = next(it)
  except StopIteration:
    # 遇到StopIteration就退出循環(huán)
    break

等價效果(迭代器)

十一、常用模塊

(一)、導(dǎo)入模塊:導(dǎo)入模塊的本質(zhì)就是把python文件解釋一遍;導(dǎo)入包的本質(zhì)就是把包文件下面的init.py文件運(yùn)行一遍

(二)、常用模塊:

(1)time和datatime模塊
時間相關(guān)的操作,時間有三種表示方式:1、時間戳 1970年1月1日之后的秒,即:time.time()
2、格式化的字符串 2014-11-11 11:11, 即:time.strftime('%Y-%m-%d')
3、結(jié)構(gòu)化時間 元組包含了:年、日、星期等... time.struct_time 即:time.localtime()

import time
print(time.time())       #時間戳
#1472037866.0750718
print(time.localtime())    #結(jié)構(gòu)化時間
#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)
print(time.strftime('%Y-%m-%d'))  #格式化的字符串
#2016-08-25
print(time.strftime('%Y-%m-%d',time.localtime()))
#2016-08-25
print(time.gmtime())      #結(jié)構(gòu)化時間
#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)
print(time.strptime('2014-11-11', '%Y-%m-%d')) #結(jié)構(gòu)化時間
#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)
print(time.asctime())
#Thu Aug 25 11:15:10 2016
print(time.asctime(time.localtime()))
#Thu Aug 25 11:15:10 2016
print(time.ctime(time.time()))
#Thu Aug 25 11:15:10 2016

time模塊
import datetime
print(datetime.date)  #表示日期的類。常用的屬性有year, month, day
#<class 'datetime.date'>
print(datetime.time)  #表示時間的類。常用的屬性有hour, minute, second, microsecond
#<class 'datetime.time'>
print(datetime.datetime)    #表示日期時間
#<class 'datetime.datetime'>
print(datetime.timedelta)    #表示時間間隔,即兩個時間點(diǎn)之間的長度
#<class 'datetime.timedelta'>
print(datetime.datetime.now())
#2016-08-25 14:21:07.722285
print(datetime.datetime.now() - datetime.timedelta(days=5))
#2016-08-20 14:21:28.275460

datetime模塊
import time

str = '2017-03-26 3:12'
str2 = '2017-05-26 13:12'
date1 = time.strptime(str, '%Y-%m-%d %H:%M')
date2 = time.strptime(str2, '%Y-%m-%d %H:%M')
if float(time.time()) >= float(time.mktime(date1)) and float(time.time()) <= float(time.mktime(date2)):
  print 'cccccccc'


import datetime

str = '2017-03-26 3:12'
str2 = '2017-05-26 13:12'
date1 = datetime.datetime.strptime(str,'%Y-%m-%d %H:%M')
date2 = datetime.datetime.strptime(str2,'%Y-%m-%d %H:%M')
datenow = datetime.datetime.now()
if datenow <date1:
  print 'dddddd'

時間比較

時間比較

(2)andom模塊:生成隨機(jī)數(shù)(驗證碼)

#random隨機(jī)數(shù)模塊
import random
print(random.random())   #生成0到1的隨機(jī)數(shù)
#0.7308387398872364
print(random.randint(1,3)) #生成1-3隨機(jī)數(shù)
#3
print(random.randrange(1,3)) #生成1-2隨機(jī)數(shù),不包含3
#2
print(random.choice("hello")) #隨機(jī)選取字符串
#e
print(random.sample("hello",2))   #隨機(jī)選取特定的字符
#['l', 'h']
items = [1,2,3,4,5,6,7]
random.shuffle(items)
print(items)
#[2, 3, 1, 6, 4, 7, 5]

生成隨機(jī)數(shù)
import random
checkcode = ''
for i in range(4):
  current = random.randrange(0,4)
  if current != i:
    temp = chr(random.randint(65,90))
  else:
    temp = random.randint(0,9)
  checkcode += str(temp)
print(checkcode)
#51T6

驗證碼

(3)os模塊:用于提供系統(tǒng)級別的操作(比如目錄、路徑等的操作)

import os
os.getcwd() #獲取當(dāng)前工作目錄,即當(dāng)前python腳本工作的目錄路徑
os.chdir("dirname") #改變當(dāng)前腳本工作目錄;相當(dāng)于shell下cd
os.curdir #返回當(dāng)前目錄: ('.')
os.pardir #獲取當(dāng)前目錄的父目錄字符串名:('..')
os.makedirs('dirname1/dirname2')  #可生成多層遞歸目錄
os.removedirs('dirname1')  # 若目錄為空,則刪除,并遞歸到上一級目錄,如若也為空,則刪除,依此類推
os.mkdir('dirname')  # 生成單級目錄;相當(dāng)于shell中mkdir dirname
os.rmdir('dirname')  #刪除單級空目錄,若目錄不為空則無法刪除,報錯;相當(dāng)于shell中rmdir dirname
os.listdir('dirname')  #列出指定目錄下的所有文件和子目錄,包括隱藏文件,并以列表方式打印
os.remove() # 刪除一個文件
os.rename("oldname","newname") # 重命名文件/目錄
os.stat('path/filename') # 獲取文件/目錄信息
os.sep  #輸出操作系統(tǒng)特定的路徑分隔符,win下為"\\",Linux下為"/"
os.linesep  #輸出當(dāng)前平臺使用的行終止符,win下為"\t\n",Linux下為"\n"
os.pathsep  #輸出用于分割文件路徑的字符串
os.name  #輸出字符串指示當(dāng)前使用平臺。win->'nt'; Linux->'posix'
os.system("bash command") #運(yùn)行shell命令,直接顯示
os.environ #獲取系統(tǒng)環(huán)境變量
os.path.abspath(path) #返回path規(guī)范化的絕對路徑
os.path.split(path) #將path分割成目錄和文件名二元組返回
os.path.dirname(path) # 返回path的目錄。其實(shí)就是os.path.split(path)的第一個元素
os.path.basename(path) # 返回path最后的文件名。如何path以/或\結(jié)尾,那么就會返回空值。即os.path.split(path)的第二個元素
os.path.exists(path) #如果path存在,返回True;如果path不存在,返回False
os.path.isabs(path) #如果path是絕對路徑,返回True
os.path.isfile(path) #如果path是一個存在的文件,返回True。否則返回False
os.path.isdir(path) #如果path是一個存在的目錄,則返回True。否則返回False
os.path.join(path1[, path2[, ...]]) # 將多個路徑組合后返回,第一個絕對路徑之前的參數(shù)將被忽略
os.path.getatime(path) #返回path所指向的文件或者目錄的最后存取時間
os.path.getmtime(path) #返回path所指向的文件或者目錄的最后修改時間

os模塊

(4)sys模塊:用于提供對解釋器相關(guān)的操作(比如退出程序、版本信息等)

import sys
sys.argv      #命令行參數(shù)List,第一個元素是程序本身路徑
sys.exit(n)    #退出程序,正常退出時exit(0)
sys.version    # 獲取Python解釋程序的版本信息
sys.maxint     #最大的Int值
sys.path      #返回模塊的搜索路徑,初始化時使用PYTHONPATH環(huán)境變量的值
sys.platform   #返回操作系統(tǒng)平臺名稱
sys.stdout.write('please:')
val = sys.stdin.readline()[:-1]

sys模塊

(5)shutil模塊:高級的(文件、文件夾、壓縮包)處理模塊 (比如文件的拷貝、壓縮等)

① shutil.copyfileobj 將文件內(nèi)容拷貝到另一個文件中,可以部分內(nèi)容

def copyfileobj(fsrc, fdst, length=16*1024):
  """copy data from file-like object fsrc to file-like object fdst"""
  while 1:
    buf = fsrc.read(length)
    if not buf:
      break
    fdst.write(buf)

shutil.copyfileobj
import shutil
f1 = open("fsrc",encoding="utf-8")
f2 = open("fdst",encoding="utf-8")
shutil.copyfile(f1,f2)
#把文件f1里的內(nèi)容拷貝到f2當(dāng)中

② shutil.copyfile 文件拷貝

def copyfile(src, dst):
  """Copy data from src to dst"""
  if _samefile(src, dst):
    raise Error("`%s` and `%s` are the same file" % (src, dst))
  for fn in [src, dst]:
    try:
      st = os.stat(fn)
    except OSError:
      # File most likely does not exist
      pass
    else:
      # XXX What about other special files? (sockets, devices...)
      if stat.S_ISFIFO(st.st_mode):
        raise SpecialFileError("`%s` is a named pipe" % fn)
  with open(src, 'rb') as fsrc:
    with open(dst, 'wb') as fdst:
      copyfileobj(fsrc, fdst)

shutil.copyfile
import shutil
shutil.copyfile("f1","f2")
#把文件f1里的內(nèi)容拷貝到f2當(dāng)中

③ shutil.copymode(src, dst) 僅拷貝權(quán)限。內(nèi)容、組、用戶均不變

def copymode(src, dst):
  """Copy mode bits from src to dst"""
  if hasattr(os, 'chmod'):
    st = os.stat(src)
    mode = stat.S_IMODE(st.st_mode)
    os.chmod(dst, mode)

shutil.copymode

④ shutil.copystat(src, dst) 拷貝狀態(tài)的信息,包括:mode bits, atime, mtime, flags

def copystat(src, dst):
  """Copy all stat info (mode bits, atime, mtime, flags) from src to dst"""
  st = os.stat(src)
  mode = stat.S_IMODE(st.st_mode)
  if hasattr(os, 'utime'):
    os.utime(dst, (st.st_atime, st.st_mtime))
  if hasattr(os, 'chmod'):
    os.chmod(dst, mode)
  if hasattr(os, 'chflags') and hasattr(st, 'st_flags'):
    try:
      os.chflags(dst, st.st_flags)
    except OSError, why:
      for err in 'EOPNOTSUPP', 'ENOTSUP':
        if hasattr(errno, err) and why.errno == getattr(errno, err):
          break
      else:
        raise

shutil.copystat

⑤ shutil.copy(src, dst) 拷貝文件和權(quán)限

def copy(src, dst):
  """Copy data and mode bits ("cp src dst").

  The destination may be a directory.

  """
  if os.path.isdir(dst):
    dst = os.path.join(dst, os.path.basename(src))
  copyfile(src, dst)
  copymode(src, dst)

shutil.copy

⑥ shutil.copy2(src, dst) 拷貝文件和狀態(tài)信息

def copy2(src, dst):
  """Copy data and all stat info ("cp -p src dst").

  The destination may be a directory.

  """
  if os.path.isdir(dst):
    dst = os.path.join(dst, os.path.basename(src))
  copyfile(src, dst)
  copystat(src, dst)

shutil.copy2

⑦ shutil.copytree(src, dst, symlinks=False, ignore=None) 遞歸的去拷貝文件 拷貝多層目錄

def ignore_patterns(*patterns):
  """Function that can be used as copytree() ignore parameter.

  Patterns is a sequence of glob-style patterns
  that are used to exclude files"""
  def _ignore_patterns(path, names):
    ignored_names = []
    for pattern in patterns:
      ignored_names.extend(fnmatch.filter(names, pattern))
    return set(ignored_names)
  return _ignore_patterns
def copytree(src, dst, symlinks=False, ignore=None):
  """Recursively copy a directory tree using copy2().

  The destination directory must not already exist.
  If exception(s) occur, an Error is raised with a list of reasons.

  If the optional symlinks flag is true, symbolic links in the
  source tree result in symbolic links in the destination tree; if
  it is false, the contents of the files pointed to by symbolic
  links are copied.

  The optional ignore argument is a callable. If given, it
  is called with the `src` parameter, which is the directory
  being visited by copytree(), and `names` which is the list of
  `src` contents, as returned by os.listdir():

    callable(src, names) -> ignored_names

  Since copytree() is called recursively, the callable will be
  called once for each directory that is copied. It returns a
  list of names relative to the `src` directory that should
  not be copied.

  XXX Consider this example code rather than the ultimate tool.

  """
  names = os.listdir(src)
  if ignore is not None:
    ignored_names = ignore(src, names)
  else:
    ignored_names = set()

  os.makedirs(dst)
  errors = []
  for name in names:
    if name in ignored_names:
      continue
    srcname = os.path.join(src, name)
    dstname = os.path.join(dst, name)
    try:
      if symlinks and os.path.islink(srcname):
        linkto = os.readlink(srcname)
        os.symlink(linkto, dstname)
      elif os.path.isdir(srcname):
        copytree(srcname, dstname, symlinks, ignore)
      else:
        # Will raise a SpecialFileError for unsupported file types        copy2(srcname, dstname)
    # catch the Error from the recursive copytree so that we can
    # continue with other files
    except Error, err:
      errors.extend(err.args[0])
    except EnvironmentError, why:
      errors.append((srcname, dstname, str(why)))
  try:
    copystat(src, dst)
  except OSError, why:
    if WindowsError is not None and isinstance(why, WindowsError):
      # Copying file access times may fail on Windows
      pass
    else:
      errors.append((src, dst, str(why)))
  if errors:
    raise Error, errors

shutil.copytree

⑧ shutil.rmtree(path[, ignore_errors[, onerror]]) 遞歸的去刪除文件

def rmtree(path, ignore_errors=False, onerror=None):
  """Recursively delete a directory tree.

  If ignore_errors is set, errors are ignored; otherwise, if onerror
  is set, it is called to handle the error with arguments (func,
  path, exc_info) where func is os.listdir, os.remove, or os.rmdir;
  path is the argument to that function that caused it to fail; and
  exc_info is a tuple returned by sys.exc_info(). If ignore_errors
  is false and onerror is None, an exception is raised.

  """
  if ignore_errors:
    def onerror(*args):
      pass
  elif onerror is None:
    def onerror(*args):
      raise
  try:
    if os.path.islink(path):
      # symlinks to directories are forbidden, see bug #1669
      raise OSError("Cannot call rmtree on a symbolic link")
  except OSError:
    onerror(os.path.islink, path, sys.exc_info())
    # can't continue even if onerror hook returns
    return
  names = []
  try:
    names = os.listdir(path)
  except os.error, err:
    onerror(os.listdir, path, sys.exc_info())
  for name in names:
    fullname = os.path.join(path, name)
    try:
      mode = os.lstat(fullname).st_mode
    except os.error:
      mode = 0
    if stat.S_ISDIR(mode):
      rmtree(fullname, ignore_errors, onerror)
    else:
      try:
        os.remove(fullname)
      except os.error, err:
        onerror(os.remove, fullname, sys.exc_info())
  try:
    os.rmdir(path)
  except os.error:
    onerror(os.rmdir, path, sys.exc_info())

shutil.rmtree

⑨ shutil.move(src, dst) 遞歸的去移動文件

def move(src, dst):
  """Recursively move a file or directory to another location. This is
  similar to the Unix "mv" command.

  If the destination is a directory or a symlink to a directory, the source
  is moved inside the directory. The destination path must not already
  exist.

  If the destination already exists but is not a directory, it may be
  overwritten depending on os.rename() semantics.

  If the destination is on our current filesystem, then rename() is used.
  Otherwise, src is copied to the destination and then removed.
  A lot more could be done here... A look at a mv.c shows a lot of
  the issues this implementation glosses over.

  """
  real_dst = dst
  if os.path.isdir(dst):
    if _samefile(src, dst):
      # We might be on a case insensitive filesystem,
      # perform the rename anyway.      os.rename(src, dst)
      return

    real_dst = os.path.join(dst, _basename(src))
    if os.path.exists(real_dst):
      raise Error, "Destination path '%s' already exists" % real_dst
  try:
    os.rename(src, real_dst)
  except OSError:
    if os.path.isdir(src):
      if _destinsrc(src, dst):
        raise Error, "Cannot move a directory '%s' into itself '%s'." % (src, dst)
      copytree(src, real_dst, symlinks=True)
      rmtree(src)
    else:
      copy2(src, real_dst)
      os.unlink(src)

shutil.move

⑩ shutil.make_archive(base_name, format,...) 創(chuàng)建壓縮包并返回文件路徑,例如:zip、tar
base_name: 壓縮包的文件名,也可以是壓縮包的路徑。只是文件名時,則保存至當(dāng)前目錄,否則保存至指定路徑,
        如:www                        =>保存至當(dāng)前路徑
        如:/Users/wupeiqi/www =>保存至/Users/wupeiqi/
format: 壓縮包種類,“zip”, “tar”, “bztar”,“gztar”
root_dir: 要壓縮的文件夾路徑(默認(rèn)當(dāng)前目錄)
owner: 用戶,默認(rèn)當(dāng)前用戶
group: 組,默認(rèn)當(dāng)前組
logger: 用于記錄日志,通常是logging.Logger對象

def make_archive(base_name, format, root_dir=None, base_dir=None, verbose=0,
         dry_run=0, owner=None, group=None, logger=None):
  """Create an archive file (eg. zip or tar).

  'base_name' is the name of the file to create, minus any format-specific
  extension; 'format' is the archive format: one of "zip", "tar", "bztar"
  or "gztar".

  'root_dir' is a directory that will be the root directory of the
  archive; ie. we typically chdir into 'root_dir' before creating the
  archive. 'base_dir' is the directory where we start archiving from;
  ie. 'base_dir' will be the common prefix of all files and
  directories in the archive. 'root_dir' and 'base_dir' both default
  to the current directory. Returns the name of the archive file.

  'owner' and 'group' are used when creating a tar archive. By default,
  uses the current owner and group.
  """
  save_cwd = os.getcwd()
  if root_dir is not None:
    if logger is not None:
      logger.debug("changing into '%s'", root_dir)
    base_name = os.path.abspath(base_name)
    if not dry_run:
      os.chdir(root_dir)

  if base_dir is None:
    base_dir = os.curdir

  kwargs = {'dry_run': dry_run, 'logger': logger}

  try:
    format_info = _ARCHIVE_FORMATS[format]
  except KeyError:
    raise ValueError, "unknown archive format '%s'" % format

  func = format_info[0]
  for arg, val in format_info[1]:
    kwargs[arg] = val

  if format != 'zip':
    kwargs['owner'] = owner
    kwargs['group'] = group

  try:
    filename = func(base_name, base_dir, **kwargs)
  finally:
    if root_dir is not None:
      if logger is not None:
        logger.debug("changing back to '%s'", save_cwd)
      os.chdir(save_cwd)

  return filename

源碼

源碼

shutil 對壓縮包的處理是調(diào)用 ZipFile 和 TarFile 兩個模塊來進(jìn)行的,詳細(xì):

import zipfile

# 壓縮
z = zipfile.ZipFile('laxi.zip', 'w')
z.write('a.log')
z.write('data.data')
z.close()

# 解壓
z = zipfile.ZipFile('laxi.zip', 'r')
z.extractall()
z.close()

zipfile 壓縮解壓

zipfile 壓縮解壓

zipfile 壓縮解壓
import tarfile

# 壓縮
tar = tarfile.open('your.tar','w')
tar.add('/Users/wupeiqi/PycharmProjects/bbs2.zip', arcname='bbs2.zip')
tar.add('/Users/wupeiqi/PycharmProjects/cmdb.zip', arcname='cmdb.zip')
tar.close()

# 解壓
tar = tarfile.open('your.tar','r')
tar.extractall() # 可設(shè)置解壓地址
tar.close()

tarfile 壓縮解壓

tarfile 壓縮解壓

tarfile 壓縮解壓
class ZipFile(object):
  """ Class with methods to open, read, write, close, list zip files.

  z = ZipFile(file, mode="r", compression=ZIP_STORED, allowZip64=False)

  file: Either the path to the file, or a file-like object.
     If it is a path, the file will be opened and closed by ZipFile.
  mode: The mode can be either read "r", write "w" or append "a".
  compression: ZIP_STORED (no compression) or ZIP_DEFLATED (requires zlib).
  allowZip64: if True ZipFile will create files with ZIP64 extensions when
        needed, otherwise it will raise an exception when this would
        be necessary.

  """

  fp = None          # Set here since __del__ checks it

  def __init__(self, file, mode="r", compression=ZIP_STORED, allowZip64=False):
    """Open the ZIP file with mode read "r", write "w" or append "a"."""
    if mode not in ("r", "w", "a"):
      raise RuntimeError('ZipFile() requires mode "r", "w", or "a"')

    if compression == ZIP_STORED:
      pass
    elif compression == ZIP_DEFLATED:
      if not zlib:
        raise RuntimeError,\
           "Compression requires the (missing) zlib module"
    else:
      raise RuntimeError, "That compression method is not supported"

    self._allowZip64 = allowZip64
    self._didModify = False
    self.debug = 0 # Level of printing: 0 through 3
    self.NameToInfo = {}  # Find file info given name
    self.filelist = []   # List of ZipInfo instances for archive
    self.compression = compression # Method of compression
    self.mode = key = mode.replace('b', '')[0]
    self.pwd = None
    self._comment = ''

    # Check if we were passed a file-like object
    if isinstance(file, basestring):
      self._filePassed = 0
      self.filename = file
      modeDict = {'r' : 'rb', 'w': 'wb', 'a' : 'r+b'}
      try:
        self.fp = open(file, modeDict[mode])
      except IOError:
        if mode == 'a':
          mode = key = 'w'
          self.fp = open(file, modeDict[mode])
        else:
          raise
    else:
      self._filePassed = 1
      self.fp = file
      self.filename = getattr(file, 'name', None)

    try:
      if key == 'r':
        self._RealGetContents()
      elif key == 'w':
        # set the modified flag so central directory gets written
        # even if no files are added to the archive
        self._didModify = True
      elif key == 'a':
        try:
          # See if file is a zip file
          self._RealGetContents()
          # seek to start of directory and overwrite
          self.fp.seek(self.start_dir, 0)
        except BadZipfile:
          # file is not a zip file, just append
          self.fp.seek(0, 2)

          # set the modified flag so central directory gets written
          # even if no files are added to the archive
          self._didModify = True
      else:
        raise RuntimeError('Mode must be "r", "w" or "a"')
    except:
      fp = self.fp
      self.fp = None
      if not self._filePassed:
        fp.close()
      raise

  def __enter__(self):
    return self

  def __exit__(self, type, value, traceback):
    self.close()

  def _RealGetContents(self):
    """Read in the table of contents for the ZIP file."""
    fp = self.fp
    try:
      endrec = _EndRecData(fp)
    except IOError:
      raise BadZipfile("File is not a zip file")
    if not endrec:
      raise BadZipfile, "File is not a zip file"
    if self.debug > 1:
      print endrec
    size_cd = endrec[_ECD_SIZE]       # bytes in central directory
    offset_cd = endrec[_ECD_OFFSET]     # offset of central directory
    self._comment = endrec[_ECD_COMMENT]  # archive comment

    # "concat" is zero, unless zip was concatenated to another file
    concat = endrec[_ECD_LOCATION] - size_cd - offset_cd
    if endrec[_ECD_SIGNATURE] == stringEndArchive64:
      # If Zip64 extension structures are present, account for them
      concat -= (sizeEndCentDir64 + sizeEndCentDir64Locator)

    if self.debug > 2:
      inferred = concat + offset_cd
      print "given, inferred, offset", offset_cd, inferred, concat
    # self.start_dir: Position of start of central directory
    self.start_dir = offset_cd + concat
    fp.seek(self.start_dir, 0)
    data = fp.read(size_cd)
    fp = cStringIO.StringIO(data)
    total = 0
    while total < size_cd:
      centdir = fp.read(sizeCentralDir)
      if len(centdir) != sizeCentralDir:
        raise BadZipfile("Truncated central directory")
      centdir = struct.unpack(structCentralDir, centdir)
      if centdir[_CD_SIGNATURE] != stringCentralDir:
        raise BadZipfile("Bad magic number for central directory")
      if self.debug > 2:
        print centdir
      filename = fp.read(centdir[_CD_FILENAME_LENGTH])
      # Create ZipInfo instance to store file information
      x = ZipInfo(filename)
      x.extra = fp.read(centdir[_CD_EXTRA_FIELD_LENGTH])
      x.comment = fp.read(centdir[_CD_COMMENT_LENGTH])
      x.header_offset = centdir[_CD_LOCAL_HEADER_OFFSET]
      (x.create_version, x.create_system, x.extract_version, x.reserved,
        x.flag_bits, x.compress_type, t, d,
        x.CRC, x.compress_size, x.file_size) = centdir[1:12]
      x.volume, x.internal_attr, x.external_attr = centdir[15:18]
      # Convert date/time code to (year, month, day, hour, min, sec)
      x._raw_time = t
      x.date_time = ( (d>>9)+1980, (d>>5)&0xF, d&0x1F,
                   t>>11, (t>>5)&0x3F, (t&0x1F) * 2 )

      x._decodeExtra()
      x.header_offset = x.header_offset + concat
      x.filename = x._decodeFilename()
      self.filelist.append(x)
      self.NameToInfo[x.filename] = x

      # update total bytes read from central directory
      total = (total + sizeCentralDir + centdir[_CD_FILENAME_LENGTH]
           + centdir[_CD_EXTRA_FIELD_LENGTH]
           + centdir[_CD_COMMENT_LENGTH])

      if self.debug > 2:
        print "total", total


  def namelist(self):
    """Return a list of file names in the archive."""
    l = []
    for data in self.filelist:
      l.append(data.filename)
    return l

  def infolist(self):
    """Return a list of class ZipInfo instances for files in the
    archive."""
    return self.filelist

  def printdir(self):
    """Print a table of contents for the zip file."""
    print "%-46s %19s %12s" % ("File Name", "Modified  ", "Size")
    for zinfo in self.filelist:
      date = "%d-%02d-%02d %02d:%02d:%02d" % zinfo.date_time[:6]
      print "%-46s %s %12d" % (zinfo.filename, date, zinfo.file_size)

  def testzip(self):
    """Read all the files and check the CRC."""
    chunk_size = 2 ** 20
    for zinfo in self.filelist:
      try:
        # Read by chunks, to avoid an OverflowError or a
        # MemoryError with very large embedded files.
        with self.open(zinfo.filename, "r") as f:
          while f.read(chunk_size):   # Check CRC-32
            pass
      except BadZipfile:
        return zinfo.filename

  def getinfo(self, name):
    """Return the instance of ZipInfo given 'name'."""
    info = self.NameToInfo.get(name)
    if info is None:
      raise KeyError(
        'There is no item named %r in the archive' % name)

    return info

  def setpassword(self, pwd):
    """Set default password for encrypted files."""
    self.pwd = pwd

  @property
  def comment(self):
    """The comment text associated with the ZIP file."""
    return self._comment

  @comment.setter
  def comment(self, comment):
    # check for valid comment length
    if len(comment) > ZIP_MAX_COMMENT:
      import warnings
      warnings.warn('Archive comment is too long; truncating to %d bytes'
             % ZIP_MAX_COMMENT, stacklevel=2)
      comment = comment[:ZIP_MAX_COMMENT]
    self._comment = comment
    self._didModify = True

  def read(self, name, pwd=None):
    """Return file bytes (as a string) for name."""
    return self.open(name, "r", pwd).read()

  def open(self, name, mode="r", pwd=None):
    """Return file-like object for 'name'."""
    if mode not in ("r", "U", "rU"):
      raise RuntimeError, 'open() requires mode "r", "U", or "rU"'
    if not self.fp:
      raise RuntimeError, \
         "Attempt to read ZIP archive that was already closed"

    # Only open a new file for instances where we were not
    # given a file object in the constructor
    if self._filePassed:
      zef_file = self.fp
      should_close = False
    else:
      zef_file = open(self.filename, 'rb')
      should_close = True

    try:
      # Make sure we have an info object
      if isinstance(name, ZipInfo):
        # 'name' is already an info object
        zinfo = name
      else:
        # Get info object for name
        zinfo = self.getinfo(name)

      zef_file.seek(zinfo.header_offset, 0)

      # Skip the file header:
      fheader = zef_file.read(sizeFileHeader)
      if len(fheader) != sizeFileHeader:
        raise BadZipfile("Truncated file header")
      fheader = struct.unpack(structFileHeader, fheader)
      if fheader[_FH_SIGNATURE] != stringFileHeader:
        raise BadZipfile("Bad magic number for file header")

      fname = zef_file.read(fheader[_FH_FILENAME_LENGTH])
      if fheader[_FH_EXTRA_FIELD_LENGTH]:
        zef_file.read(fheader[_FH_EXTRA_FIELD_LENGTH])

      if fname != zinfo.orig_filename:
        raise BadZipfile, \
            'File name in directory "%s" and header "%s" differ.' % (
              zinfo.orig_filename, fname)

      # check for encrypted flag & handle password
      is_encrypted = zinfo.flag_bits & 0x1
      zd = None
      if is_encrypted:
        if not pwd:
          pwd = self.pwd
        if not pwd:
          raise RuntimeError, "File %s is encrypted, " \
            "password required for extraction" % name

        zd = _ZipDecrypter(pwd)
        # The first 12 bytes in the cypher stream is an encryption header
        # used to strengthen the algorithm. The first 11 bytes are
        # completely random, while the 12th contains the MSB of the CRC,
        # or the MSB of the file time depending on the header type
        # and is used to check the correctness of the password.
        bytes = zef_file.read(12)
        h = map(zd, bytes[0:12])
        if zinfo.flag_bits & 0x8:
          # compare against the file type from extended local headers
          check_byte = (zinfo._raw_time >> 8) & 0xff
        else:
          # compare against the CRC otherwise
          check_byte = (zinfo.CRC >> 24) & 0xff
        if ord(h[11]) != check_byte:
          raise RuntimeError("Bad password for file", name)

      return ZipExtFile(zef_file, mode, zinfo, zd,
          close_fileobj=should_close)
    except:
      if should_close:
        zef_file.close()
      raise

  def extract(self, member, path=None, pwd=None):
    """Extract a member from the archive to the current working directory,
      using its full name. Its file information is extracted as accurately
      as possible. `member' may be a filename or a ZipInfo object. You can
      specify a different directory using `path'.
    """
    if not isinstance(member, ZipInfo):
      member = self.getinfo(member)

    if path is None:
      path = os.getcwd()

    return self._extract_member(member, path, pwd)

  def extractall(self, path=None, members=None, pwd=None):
    """Extract all members from the archive to the current working
      directory. `path' specifies a different directory to extract to.
      `members' is optional and must be a subset of the list returned
      by namelist().
    """
    if members is None:
      members = self.namelist()

    for zipinfo in members:
      self.extract(zipinfo, path, pwd)

  def _extract_member(self, member, targetpath, pwd):
    """Extract the ZipInfo object 'member' to a physical
      file on the path targetpath.
    """
    # build the destination pathname, replacing
    # forward slashes to platform specific separators.
    arcname = member.filename.replace('/', os.path.sep)

    if os.path.altsep:
      arcname = arcname.replace(os.path.altsep, os.path.sep)
    # interpret absolute pathname as relative, remove drive letter or
    # UNC path, redundant separators, "." and ".." components.
    arcname = os.path.splitdrive(arcname)[1]
    arcname = os.path.sep.join(x for x in arcname.split(os.path.sep)
          if x not in ('', os.path.curdir, os.path.pardir))
    if os.path.sep == '\\':
      # filter illegal characters on Windows
      illegal = ':<>|"?*'
      if isinstance(arcname, unicode):
        table = {ord(c): ord('_') for c in illegal}
      else:
        table = string.maketrans(illegal, '_' * len(illegal))
      arcname = arcname.translate(table)
      # remove trailing dots
      arcname = (x.rstrip('.') for x in arcname.split(os.path.sep))
      arcname = os.path.sep.join(x for x in arcname if x)

    targetpath = os.path.join(targetpath, arcname)
    targetpath = os.path.normpath(targetpath)

    # Create all upper directories if necessary.
    upperdirs = os.path.dirname(targetpath)
    if upperdirs and not os.path.exists(upperdirs):
      os.makedirs(upperdirs)

    if member.filename[-1] == '/':
      if not os.path.isdir(targetpath):
        os.mkdir(targetpath)
      return targetpath

    with self.open(member, pwd=pwd) as source, \
       file(targetpath, "wb") as target:
      shutil.copyfileobj(source, target)

    return targetpath

  def _writecheck(self, zinfo):
    """Check for errors before writing a file to the archive."""
    if zinfo.filename in self.NameToInfo:
      import warnings
      warnings.warn('Duplicate name: %r' % zinfo.filename, stacklevel=3)
    if self.mode not in ("w", "a"):
      raise RuntimeError, 'write() requires mode "w" or "a"'
    if not self.fp:
      raise RuntimeError, \
         "Attempt to write ZIP archive that was already closed"
    if zinfo.compress_type == ZIP_DEFLATED and not zlib:
      raise RuntimeError, \
         "Compression requires the (missing) zlib module"
    if zinfo.compress_type not in (ZIP_STORED, ZIP_DEFLATED):
      raise RuntimeError, \
         "That compression method is not supported"
    if not self._allowZip64:
      requires_zip64 = None
      if len(self.filelist) >= ZIP_FILECOUNT_LIMIT:
        requires_zip64 = "Files count"
      elif zinfo.file_size > ZIP64_LIMIT:
        requires_zip64 = "Filesize"
      elif zinfo.header_offset > ZIP64_LIMIT:
        requires_zip64 = "Zipfile size"
      if requires_zip64:
        raise LargeZipFile(requires_zip64 +
                  " would require ZIP64 extensions")

  def write(self, filename, arcname=None, compress_type=None):
    """Put the bytes from filename into the archive under the name
    arcname."""
    if not self.fp:
      raise RuntimeError(
         "Attempt to write to ZIP archive that was already closed")

    st = os.stat(filename)
    isdir = stat.S_ISDIR(st.st_mode)
    mtime = time.localtime(st.st_mtime)
    date_time = mtime[0:6]
    # Create ZipInfo instance to store file information
    if arcname is None:
      arcname = filename
    arcname = os.path.normpath(os.path.splitdrive(arcname)[1])
    while arcname[0] in (os.sep, os.altsep):
      arcname = arcname[1:]
    if isdir:
      arcname += '/'
    zinfo = ZipInfo(arcname, date_time)
    zinfo.external_attr = (st[0] & 0xFFFF) << 16L   # Unix attributes
    if compress_type is None:
      zinfo.compress_type = self.compression
    else:
      zinfo.compress_type = compress_type

    zinfo.file_size = st.st_size
    zinfo.flag_bits = 0x00
    zinfo.header_offset = self.fp.tell()  # Start of header bytes

    self._writecheck(zinfo)
    self._didModify = True

    if isdir:
      zinfo.file_size = 0
      zinfo.compress_size = 0
      zinfo.CRC = 0
      zinfo.external_attr |= 0x10 # MS-DOS directory flag
      self.filelist.append(zinfo)
      self.NameToInfo[zinfo.filename] = zinfo
      self.fp.write(zinfo.FileHeader(False))
      return

    with open(filename, "rb") as fp:
      # Must overwrite CRC and sizes with correct data later
      zinfo.CRC = CRC = 0
      zinfo.compress_size = compress_size = 0
      # Compressed size can be larger than uncompressed size
      zip64 = self._allowZip64 and \
          zinfo.file_size * 1.05 > ZIP64_LIMIT
      self.fp.write(zinfo.FileHeader(zip64))
      if zinfo.compress_type == ZIP_DEFLATED:
        cmpr = zlib.compressobj(zlib.Z_DEFAULT_COMPRESSION,
           zlib.DEFLATED, -15)
      else:
        cmpr = None
      file_size = 0
      while 1:
        buf = fp.read(1024 * 8)
        if not buf:
          break
        file_size = file_size + len(buf)
        CRC = crc32(buf, CRC) & 0xffffffff
        if cmpr:
          buf = cmpr.compress(buf)
          compress_size = compress_size + len(buf)
        self.fp.write(buf)
    if cmpr:
      buf = cmpr.flush()
      compress_size = compress_size + len(buf)
      self.fp.write(buf)
      zinfo.compress_size = compress_size
    else:
      zinfo.compress_size = file_size
    zinfo.CRC = CRC
    zinfo.file_size = file_size
    if not zip64 and self._allowZip64:
      if file_size > ZIP64_LIMIT:
        raise RuntimeError('File size has increased during compressing')
      if compress_size > ZIP64_LIMIT:
        raise RuntimeError('Compressed size larger than uncompressed size')
    # Seek backwards and write file header (which will now include
    # correct CRC and file sizes)
    position = self.fp.tell()    # Preserve current position in file
    self.fp.seek(zinfo.header_offset, 0)
    self.fp.write(zinfo.FileHeader(zip64))
    self.fp.seek(position, 0)
    self.filelist.append(zinfo)
    self.NameToInfo[zinfo.filename] = zinfo

  def writestr(self, zinfo_or_arcname, bytes, compress_type=None):
    """Write a file into the archive. The contents is the string
    'bytes'. 'zinfo_or_arcname' is either a ZipInfo instance or
    the name of the file in the archive."""
    if not isinstance(zinfo_or_arcname, ZipInfo):
      zinfo = ZipInfo(filename=zinfo_or_arcname,
              date_time=time.localtime(time.time())[:6])

      zinfo.compress_type = self.compression
      if zinfo.filename[-1] == '/':
        zinfo.external_attr = 0o40775 << 16  # drwxrwxr-x
        zinfo.external_attr |= 0x10      # MS-DOS directory flag
      else:
        zinfo.external_attr = 0o600 << 16   # ?rw-------
    else:
      zinfo = zinfo_or_arcname

    if not self.fp:
      raise RuntimeError(
         "Attempt to write to ZIP archive that was already closed")

    if compress_type is not None:
      zinfo.compress_type = compress_type

    zinfo.file_size = len(bytes)      # Uncompressed size
    zinfo.header_offset = self.fp.tell()  # Start of header bytes
    self._writecheck(zinfo)
    self._didModify = True
    zinfo.CRC = crc32(bytes) & 0xffffffff    # CRC-32 checksum
    if zinfo.compress_type == ZIP_DEFLATED:
      co = zlib.compressobj(zlib.Z_DEFAULT_COMPRESSION,
         zlib.DEFLATED, -15)
      bytes = co.compress(bytes) + co.flush()
      zinfo.compress_size = len(bytes)  # Compressed size
    else:
      zinfo.compress_size = zinfo.file_size
    zip64 = zinfo.file_size > ZIP64_LIMIT or \
        zinfo.compress_size > ZIP64_LIMIT
    if zip64 and not self._allowZip64:
      raise LargeZipFile("Filesize would require ZIP64 extensions")
    self.fp.write(zinfo.FileHeader(zip64))
    self.fp.write(bytes)
    if zinfo.flag_bits & 0x08:
      # Write CRC and file sizes after the file data
      fmt = '<LQQ' if zip64 else '<LLL'
      self.fp.write(struct.pack(fmt, zinfo.CRC, zinfo.compress_size,
         zinfo.file_size))
    self.fp.flush()
    self.filelist.append(zinfo)
    self.NameToInfo[zinfo.filename] = zinfo

  def __del__(self):
    """Call the "close()" method in case the user forgot."""
    self.close()

  def close(self):
    """Close the file, and for mode "w" and "a" write the ending
    records."""
    if self.fp is None:
      return

    try:
      if self.mode in ("w", "a") and self._didModify: # write ending records
        pos1 = self.fp.tell()
        for zinfo in self.filelist:     # write central directory
          dt = zinfo.date_time
          dosdate = (dt[0] - 1980) << 9 | dt[1] << 5 | dt[2]
          dostime = dt[3] << 11 | dt[4] << 5 | (dt[5] // 2)
          extra = []
          if zinfo.file_size > ZIP64_LIMIT \
              or zinfo.compress_size > ZIP64_LIMIT:
            extra.append(zinfo.file_size)
            extra.append(zinfo.compress_size)
            file_size = 0xffffffff
            compress_size = 0xffffffff
          else:
            file_size = zinfo.file_size
            compress_size = zinfo.compress_size

          if zinfo.header_offset > ZIP64_LIMIT:
            extra.append(zinfo.header_offset)
            header_offset = 0xffffffffL
          else:
            header_offset = zinfo.header_offset

          extra_data = zinfo.extra
          if extra:
            # Append a ZIP64 field to the extra's
            extra_data = struct.pack(
                '<HH' + 'Q'*len(extra),
                1, 8*len(extra), *extra) + extra_data

            extract_version = max(45, zinfo.extract_version)
            create_version = max(45, zinfo.create_version)
          else:
            extract_version = zinfo.extract_version
            create_version = zinfo.create_version

          try:
            filename, flag_bits = zinfo._encodeFilenameFlags()
            centdir = struct.pack(structCentralDir,
            stringCentralDir, create_version,
            zinfo.create_system, extract_version, zinfo.reserved,
            flag_bits, zinfo.compress_type, dostime, dosdate,
            zinfo.CRC, compress_size, file_size,
            len(filename), len(extra_data), len(zinfo.comment),
            0, zinfo.internal_attr, zinfo.external_attr,
            header_offset)
          except DeprecationWarning:
            print >>sys.stderr, (structCentralDir,
            stringCentralDir, create_version,
            zinfo.create_system, extract_version, zinfo.reserved,
            zinfo.flag_bits, zinfo.compress_type, dostime, dosdate,
            zinfo.CRC, compress_size, file_size,
            len(zinfo.filename), len(extra_data), len(zinfo.comment),
            0, zinfo.internal_attr, zinfo.external_attr,
            header_offset)
            raise
          self.fp.write(centdir)
          self.fp.write(filename)
          self.fp.write(extra_data)
          self.fp.write(zinfo.comment)

        pos2 = self.fp.tell()
        # Write end-of-zip-archive record
        centDirCount = len(self.filelist)
        centDirSize = pos2 - pos1
        centDirOffset = pos1
        requires_zip64 = None
        if centDirCount > ZIP_FILECOUNT_LIMIT:
          requires_zip64 = "Files count"
        elif centDirOffset > ZIP64_LIMIT:
          requires_zip64 = "Central directory offset"
        elif centDirSize > ZIP64_LIMIT:
          requires_zip64 = "Central directory size"
        if requires_zip64:
          # Need to write the ZIP64 end-of-archive records
          if not self._allowZip64:
            raise LargeZipFile(requires_zip64 +
                      " would require ZIP64 extensions")
          zip64endrec = struct.pack(
              structEndArchive64, stringEndArchive64,
              44, 45, 45, 0, 0, centDirCount, centDirCount,
              centDirSize, centDirOffset)
          self.fp.write(zip64endrec)

          zip64locrec = struct.pack(
              structEndArchive64Locator,
              stringEndArchive64Locator, 0, pos2, 1)
          self.fp.write(zip64locrec)
          centDirCount = min(centDirCount, 0xFFFF)
          centDirSize = min(centDirSize, 0xFFFFFFFF)
          centDirOffset = min(centDirOffset, 0xFFFFFFFF)

        endrec = struct.pack(structEndArchive, stringEndArchive,
                  0, 0, centDirCount, centDirCount,
                  centDirSize, centDirOffset, len(self._comment))
        self.fp.write(endrec)
        self.fp.write(self._comment)
        self.fp.flush()
    finally:
      fp = self.fp
      self.fp = None
      if not self._filePassed:
        fp.close()

ZipFile

ZipFile 源碼

ZipFile 源碼
class TarFile(object):
  """The TarFile Class provides an interface to tar archives.
  """

  debug = 0          # May be set from 0 (no msgs) to 3 (all msgs)

  dereference = False     # If true, add content of linked file to the
                # tar file, else the link.

  ignore_zeros = False    # If true, skips empty or invalid blocks and
                # continues processing.

  errorlevel = 1       # If 0, fatal errors only appear in debug
                # messages (if debug >= 0). If > 0, errors
                # are passed to the caller as exceptions.

  format = DEFAULT_FORMAT   # The format to use when creating an archive.

  encoding = ENCODING     # Encoding for 8-bit character strings.

  errors = None        # Error handler for unicode conversion.

  tarinfo = TarInfo      # The default TarInfo class to use.

  fileobject = ExFileObject  # The default ExFileObject class to use.

  def __init__(self, name=None, mode="r", fileobj=None, format=None,
      tarinfo=None, dereference=None, ignore_zeros=None, encoding=None,
      errors=None, pax_headers=None, debug=None, errorlevel=None):
    """Open an (uncompressed) tar archive `name'. `mode' is either 'r' to
      read from an existing archive, 'a' to append data to an existing
      file or 'w' to create a new file overwriting an existing one. `mode'
      defaults to 'r'.
      If `fileobj' is given, it is used for reading or writing data. If it
      can be determined, `mode' is overridden by `fileobj's mode.
      `fileobj' is not closed, when TarFile is closed.
    """
    modes = {"r": "rb", "a": "r+b", "w": "wb"}
    if mode not in modes:
      raise ValueError("mode must be 'r', 'a' or 'w'")
    self.mode = mode
    self._mode = modes[mode]

    if not fileobj:
      if self.mode == "a" and not os.path.exists(name):
        # Create nonexistent files in append mode.
        self.mode = "w"
        self._mode = "wb"
      fileobj = bltn_open(name, self._mode)
      self._extfileobj = False
    else:
      if name is None and hasattr(fileobj, "name"):
        name = fileobj.name
      if hasattr(fileobj, "mode"):
        self._mode = fileobj.mode
      self._extfileobj = True
    self.name = os.path.abspath(name) if name else None
    self.fileobj = fileobj

    # Init attributes.
    if format is not None:
      self.format = format
    if tarinfo is not None:
      self.tarinfo = tarinfo
    if dereference is not None:
      self.dereference = dereference
    if ignore_zeros is not None:
      self.ignore_zeros = ignore_zeros
    if encoding is not None:
      self.encoding = encoding

    if errors is not None:
      self.errors = errors
    elif mode == "r":
      self.errors = "utf-8"
    else:
      self.errors = "strict"

    if pax_headers is not None and self.format == PAX_FORMAT:
      self.pax_headers = pax_headers
    else:
      self.pax_headers = {}

    if debug is not None:
      self.debug = debug
    if errorlevel is not None:
      self.errorlevel = errorlevel

    # Init datastructures.
    self.closed = False
    self.members = []    # list of members as TarInfo objects
    self._loaded = False  # flag if all members have been read
    self.offset = self.fileobj.tell()
                # current position in the archive file
    self.inodes = {}    # dictionary caching the inodes of
                # archive members already added

    try:
      if self.mode == "r":
        self.firstmember = None
        self.firstmember = self.next()

      if self.mode == "a":
        # Move to the end of the archive,
        # before the first empty block.
        while True:
          self.fileobj.seek(self.offset)
          try:
            tarinfo = self.tarinfo.fromtarfile(self)
            self.members.append(tarinfo)
          except EOFHeaderError:
            self.fileobj.seek(self.offset)
            break
          except HeaderError, e:
            raise ReadError(str(e))

      if self.mode in "aw":
        self._loaded = True

        if self.pax_headers:
          buf = self.tarinfo.create_pax_global_header(self.pax_headers.copy())
          self.fileobj.write(buf)
          self.offset += len(buf)
    except:
      if not self._extfileobj:
        self.fileobj.close()
      self.closed = True
      raise

  def _getposix(self):
    return self.format == USTAR_FORMAT
  def _setposix(self, value):
    import warnings
    warnings.warn("use the format attribute instead", DeprecationWarning,
           2)
    if value:
      self.format = USTAR_FORMAT
    else:
      self.format = GNU_FORMAT
  posix = property(_getposix, _setposix)

  #--------------------------------------------------------------------------
  # Below are the classmethods which act as alternate constructors to the
  # TarFile class. The open() method is the only one that is needed for
  # public use; it is the "super"-constructor and is able to select an
  # adequate "sub"-constructor for a particular compression using the mapping
  # from OPEN_METH.
  #
  # This concept allows one to subclass TarFile without losing the comfort of
  # the super-constructor. A sub-constructor is registered and made available
  # by adding it to the mapping in OPEN_METH.

  @classmethod
  def open(cls, name=None, mode="r", fileobj=None, bufsize=RECORDSIZE, **kwargs):
    """Open a tar archive for reading, writing or appending. Return
      an appropriate TarFile class.

      mode:
      'r' or 'r:*' open for reading with transparent compression
      'r:'     open for reading exclusively uncompressed
      'r:gz'    open for reading with gzip compression
      'r:bz2'   open for reading with bzip2 compression
      'a' or 'a:' open for appending, creating the file if necessary
      'w' or 'w:' open for writing without compression
      'w:gz'    open for writing with gzip compression
      'w:bz2'   open for writing with bzip2 compression

      'r|*'    open a stream of tar blocks with transparent compression
      'r|'     open an uncompressed stream of tar blocks for reading
      'r|gz'    open a gzip compressed stream of tar blocks
      'r|bz2'   open a bzip2 compressed stream of tar blocks
      'w|'     open an uncompressed stream for writing
      'w|gz'    open a gzip compressed stream for writing
      'w|bz2'   open a bzip2 compressed stream for writing
    """

    if not name and not fileobj:
      raise ValueError("nothing to open")

    if mode in ("r", "r:*"):
      # Find out which *open() is appropriate for opening the file.
      for comptype in cls.OPEN_METH:
        func = getattr(cls, cls.OPEN_METH[comptype])
        if fileobj is not None:
          saved_pos = fileobj.tell()
        try:
          return func(name, "r", fileobj, **kwargs)
        except (ReadError, CompressionError), e:
          if fileobj is not None:
            fileobj.seek(saved_pos)
          continue
      raise ReadError("file could not be opened successfully")

    elif ":" in mode:
      filemode, comptype = mode.split(":", 1)
      filemode = filemode or "r"
      comptype = comptype or "tar"

      # Select the *open() function according to
      # given compression.
      if comptype in cls.OPEN_METH:
        func = getattr(cls, cls.OPEN_METH[comptype])
      else:
        raise CompressionError("unknown compression type %r" % comptype)
      return func(name, filemode, fileobj, **kwargs)

    elif "|" in mode:
      filemode, comptype = mode.split("|", 1)
      filemode = filemode or "r"
      comptype = comptype or "tar"

      if filemode not in ("r", "w"):
        raise ValueError("mode must be 'r' or 'w'")

      stream = _Stream(name, filemode, comptype, fileobj, bufsize)
      try:
        t = cls(name, filemode, stream, **kwargs)
      except:
        stream.close()
        raise
      t._extfileobj = False
      return t

    elif mode in ("a", "w"):
      return cls.taropen(name, mode, fileobj, **kwargs)

    raise ValueError("undiscernible mode")

  @classmethod
  def taropen(cls, name, mode="r", fileobj=None, **kwargs):
    """Open uncompressed tar archive name for reading or writing.
    """
    if mode not in ("r", "a", "w"):
      raise ValueError("mode must be 'r', 'a' or 'w'")
    return cls(name, mode, fileobj, **kwargs)

  @classmethod
  def gzopen(cls, name, mode="r", fileobj=None, compresslevel=9, **kwargs):
    """Open gzip compressed tar archive name for reading or writing.
      Appending is not allowed.
    """
    if mode not in ("r", "w"):
      raise ValueError("mode must be 'r' or 'w'")

    try:
      import gzip
      gzip.GzipFile
    except (ImportError, AttributeError):
      raise CompressionError("gzip module is not available")

    try:
      fileobj = gzip.GzipFile(name, mode, compresslevel, fileobj)
    except OSError:
      if fileobj is not None and mode == 'r':
        raise ReadError("not a gzip file")
      raise

    try:
      t = cls.taropen(name, mode, fileobj, **kwargs)
    except IOError:
      fileobj.close()
      if mode == 'r':
        raise ReadError("not a gzip file")
      raise
    except:
      fileobj.close()
      raise
    t._extfileobj = False
    return t

  @classmethod
  def bz2open(cls, name, mode="r", fileobj=None, compresslevel=9, **kwargs):
    """Open bzip2 compressed tar archive name for reading or writing.
      Appending is not allowed.
    """
    if mode not in ("r", "w"):
      raise ValueError("mode must be 'r' or 'w'.")

    try:
      import bz2
    except ImportError:
      raise CompressionError("bz2 module is not available")

    if fileobj is not None:
      fileobj = _BZ2Proxy(fileobj, mode)
    else:
      fileobj = bz2.BZ2File(name, mode, compresslevel=compresslevel)

    try:
      t = cls.taropen(name, mode, fileobj, **kwargs)
    except (IOError, EOFError):
      fileobj.close()
      if mode == 'r':
        raise ReadError("not a bzip2 file")
      raise
    except:
      fileobj.close()
      raise
    t._extfileobj = False
    return t

  # All *open() methods are registered here.
  OPEN_METH = {
    "tar": "taropen",  # uncompressed tar
    "gz": "gzopen",  # gzip compressed tar
    "bz2": "bz2open"  # bzip2 compressed tar
  }

  #--------------------------------------------------------------------------
  # The public methods which TarFile provides:

  def close(self):
    """Close the TarFile. In write-mode, two finishing zero blocks are
      appended to the archive.
    """
    if self.closed:
      return

    if self.mode in "aw":
      self.fileobj.write(NUL * (BLOCKSIZE * 2))
      self.offset += (BLOCKSIZE * 2)
      # fill up the end with zero-blocks
      # (like option -b20 for tar does)
      blocks, remainder = divmod(self.offset, RECORDSIZE)
      if remainder > 0:
        self.fileobj.write(NUL * (RECORDSIZE - remainder))

    if not self._extfileobj:
      self.fileobj.close()
    self.closed = True

  def getmember(self, name):
    """Return a TarInfo object for member `name'. If `name' can not be
      found in the archive, KeyError is raised. If a member occurs more
      than once in the archive, its last occurrence is assumed to be the
      most up-to-date version.
    """
    tarinfo = self._getmember(name)
    if tarinfo is None:
      raise KeyError("filename %r not found" % name)
    return tarinfo

  def getmembers(self):
    """Return the members of the archive as a list of TarInfo objects. The
      list has the same order as the members in the archive.
    """
    self._check()
    if not self._loaded:  # if we want to obtain a list of
      self._load()    # all members, we first have to
                # scan the whole archive.
    return self.members

  def getnames(self):
    """Return the members of the archive as a list of their names. It has
      the same order as the list returned by getmembers().
    """
    return [tarinfo.name for tarinfo in self.getmembers()]

  def gettarinfo(self, name=None, arcname=None, fileobj=None):
    """Create a TarInfo object for either the file `name' or the file
      object `fileobj' (using os.fstat on its file descriptor). You can
      modify some of the TarInfo's attributes before you add it using
      addfile(). If given, `arcname' specifies an alternative name for the
      file in the archive.
    """
    self._check("aw")

    # When fileobj is given, replace name by
    # fileobj's real name.
    if fileobj is not None:
      name = fileobj.name

    # Building the name of the member in the archive.
    # Backward slashes are converted to forward slashes,
    # Absolute paths are turned to relative paths.
    if arcname is None:
      arcname = name
    drv, arcname = os.path.splitdrive(arcname)
    arcname = arcname.replace(os.sep, "/")
    arcname = arcname.lstrip("/")

    # Now, fill the TarInfo object with
    # information specific for the file.
    tarinfo = self.tarinfo()
    tarinfo.tarfile = self

    # Use os.stat or os.lstat, depending on platform
    # and if symlinks shall be resolved.
    if fileobj is None:
      if hasattr(os, "lstat") and not self.dereference:
        statres = os.lstat(name)
      else:
        statres = os.stat(name)
    else:
      statres = os.fstat(fileobj.fileno())
    linkname = ""

    stmd = statres.st_mode
    if stat.S_ISREG(stmd):
      inode = (statres.st_ino, statres.st_dev)
      if not self.dereference and statres.st_nlink > 1 and \
          inode in self.inodes and arcname != self.inodes[inode]:
        # Is it a hardlink to an already
        # archived file?
        type = LNKTYPE
        linkname = self.inodes[inode]
      else:
        # The inode is added only if its valid.
        # For win32 it is always 0.
        type = REGTYPE
        if inode[0]:
          self.inodes[inode] = arcname
    elif stat.S_ISDIR(stmd):
      type = DIRTYPE
    elif stat.S_ISFIFO(stmd):
      type = FIFOTYPE
    elif stat.S_ISLNK(stmd):
      type = SYMTYPE
      linkname = os.readlink(name)
    elif stat.S_ISCHR(stmd):
      type = CHRTYPE
    elif stat.S_ISBLK(stmd):
      type = BLKTYPE
    else:
      return None

    # Fill the TarInfo object with all
    # information we can get.
    tarinfo.name = arcname
    tarinfo.mode = stmd
    tarinfo.uid = statres.st_uid
    tarinfo.gid = statres.st_gid
    if type == REGTYPE:
      tarinfo.size = statres.st_size
    else:
      tarinfo.size = 0L
    tarinfo.mtime = statres.st_mtime
    tarinfo.type = type
    tarinfo.linkname = linkname
    if pwd:
      try:
        tarinfo.uname = pwd.getpwuid(tarinfo.uid)[0]
      except KeyError:
        pass
    if grp:
      try:
        tarinfo.gname = grp.getgrgid(tarinfo.gid)[0]
      except KeyError:
        pass

    if type in (CHRTYPE, BLKTYPE):
      if hasattr(os, "major") and hasattr(os, "minor"):
        tarinfo.devmajor = os.major(statres.st_rdev)
        tarinfo.devminor = os.minor(statres.st_rdev)
    return tarinfo

  def list(self, verbose=True):
    """Print a table of contents to sys.stdout. If `verbose' is False, only
      the names of the members are printed. If it is True, an `ls -l'-like
      output is produced.
    """
    self._check()

    for tarinfo in self:
      if verbose:
        print filemode(tarinfo.mode),
        print "%s/%s" % (tarinfo.uname or tarinfo.uid,
                 tarinfo.gname or tarinfo.gid),
        if tarinfo.ischr() or tarinfo.isblk():
          print "%10s" % ("%d,%d" \
                  % (tarinfo.devmajor, tarinfo.devminor)),
        else:
          print "%10d" % tarinfo.size,
        print "%d-%02d-%02d %02d:%02d:%02d" \
           % time.localtime(tarinfo.mtime)[:6],

      print tarinfo.name + ("/" if tarinfo.isdir() else ""),

      if verbose:
        if tarinfo.issym():
          print "->", tarinfo.linkname,
        if tarinfo.islnk():
          print "link to", tarinfo.linkname,
      print

  def add(self, name, arcname=None, recursive=True, exclude=None, filter=None):
    """Add the file `name' to the archive. `name' may be any type of file
      (directory, fifo, symbolic link, etc.). If given, `arcname'
      specifies an alternative name for the file in the archive.
      Directories are added recursively by default. This can be avoided by
      setting `recursive' to False. `exclude' is a function that should
      return True for each filename to be excluded. `filter' is a function
      that expects a TarInfo object argument and returns the changed
      TarInfo object, if it returns None the TarInfo object will be
      excluded from the archive.
    """
    self._check("aw")

    if arcname is None:
      arcname = name

    # Exclude pathnames.
    if exclude is not None:
      import warnings
      warnings.warn("use the filter argument instead",
          DeprecationWarning, 2)
      if exclude(name):
        self._dbg(2, "tarfile: Excluded %r" % name)
        return

    # Skip if somebody tries to archive the archive...
    if self.name is not None and os.path.abspath(name) == self.name:
      self._dbg(2, "tarfile: Skipped %r" % name)
      return

    self._dbg(1, name)

    # Create a TarInfo object from the file.
    tarinfo = self.gettarinfo(name, arcname)

    if tarinfo is None:
      self._dbg(1, "tarfile: Unsupported type %r" % name)
      return

    # Change or exclude the TarInfo object.
    if filter is not None:
      tarinfo = filter(tarinfo)
      if tarinfo is None:
        self._dbg(2, "tarfile: Excluded %r" % name)
        return

    # Append the tar header and data to the archive.
    if tarinfo.isreg():
      with bltn_open(name, "rb") as f:
        self.addfile(tarinfo, f)

    elif tarinfo.isdir():
      self.addfile(tarinfo)
      if recursive:
        for f in os.listdir(name):
          self.add(os.path.join(name, f), os.path.join(arcname, f),
              recursive, exclude, filter)

    else:
      self.addfile(tarinfo)

  def addfile(self, tarinfo, fileobj=None):
    """Add the TarInfo object `tarinfo' to the archive. If `fileobj' is
      given, tarinfo.size bytes are read from it and added to the archive.
      You can create TarInfo objects using gettarinfo().
      On Windows platforms, `fileobj' should always be opened with mode
      'rb' to avoid irritation about the file size.
    """
    self._check("aw")

    tarinfo = copy.copy(tarinfo)

    buf = tarinfo.tobuf(self.format, self.encoding, self.errors)
    self.fileobj.write(buf)
    self.offset += len(buf)

    # If there's data to follow, append it.
    if fileobj is not None:
      copyfileobj(fileobj, self.fileobj, tarinfo.size)
      blocks, remainder = divmod(tarinfo.size, BLOCKSIZE)
      if remainder > 0:
        self.fileobj.write(NUL * (BLOCKSIZE - remainder))
        blocks += 1
      self.offset += blocks * BLOCKSIZE

    self.members.append(tarinfo)

  def extractall(self, path=".", members=None):
    """Extract all members from the archive to the current working
      directory and set owner, modification time and permissions on
      directories afterwards. `path' specifies a different directory
      to extract to. `members' is optional and must be a subset of the
      list returned by getmembers().
    """
    directories = []

    if members is None:
      members = self

    for tarinfo in members:
      if tarinfo.isdir():
        # Extract directories with a safe mode.
        directories.append(tarinfo)
        tarinfo = copy.copy(tarinfo)
        tarinfo.mode = 0700
      self.extract(tarinfo, path)

    # Reverse sort directories.
    directories.sort(key=operator.attrgetter('name'))
    directories.reverse()

    # Set correct owner, mtime and filemode on directories.
    for tarinfo in directories:
      dirpath = os.path.join(path, tarinfo.name)
      try:
        self.chown(tarinfo, dirpath)
        self.utime(tarinfo, dirpath)
        self.chmod(tarinfo, dirpath)
      except ExtractError, e:
        if self.errorlevel > 1:
          raise
        else:
          self._dbg(1, "tarfile: %s" % e)

  def extract(self, member, path=""):
    """Extract a member from the archive to the current working directory,
      using its full name. Its file information is extracted as accurately
      as possible. `member' may be a filename or a TarInfo object. You can
      specify a different directory using `path'.
    """
    self._check("r")

    if isinstance(member, basestring):
      tarinfo = self.getmember(member)
    else:
      tarinfo = member

    # Prepare the link target for makelink().
    if tarinfo.islnk():
      tarinfo._link_target = os.path.join(path, tarinfo.linkname)

    try:
      self._extract_member(tarinfo, os.path.join(path, tarinfo.name))
    except EnvironmentError, e:
      if self.errorlevel > 0:
        raise
      else:
        if e.filename is None:
          self._dbg(1, "tarfile: %s" % e.strerror)
        else:
          self._dbg(1, "tarfile: %s %r" % (e.strerror, e.filename))
    except ExtractError, e:
      if self.errorlevel > 1:
        raise
      else:
        self._dbg(1, "tarfile: %s" % e)

  def extractfile(self, member):
    """Extract a member from the archive as a file object. `member' may be
      a filename or a TarInfo object. If `member' is a regular file, a
      file-like object is returned. If `member' is a link, a file-like
      object is constructed from the link's target. If `member' is none of
      the above, None is returned.
      The file-like object is read-only and provides the following
      methods: read(), readline(), readlines(), seek() and tell()
    """
    self._check("r")

    if isinstance(member, basestring):
      tarinfo = self.getmember(member)
    else:
      tarinfo = member

    if tarinfo.isreg():
      return self.fileobject(self, tarinfo)

    elif tarinfo.type not in SUPPORTED_TYPES:
      # If a member's type is unknown, it is treated as a
      # regular file.
      return self.fileobject(self, tarinfo)

    elif tarinfo.islnk() or tarinfo.issym():
      if isinstance(self.fileobj, _Stream):
        # A small but ugly workaround for the case that someone tries
        # to extract a (sym)link as a file-object from a non-seekable
        # stream of tar blocks.
        raise StreamError("cannot extract (sym)link as file object")
      else:
        # A (sym)link's file object is its target's file object.
        return self.extractfile(self._find_link_target(tarinfo))
    else:
      # If there's no data associated with the member (directory, chrdev,
      # blkdev, etc.), return None instead of a file object.
      return None

  def _extract_member(self, tarinfo, targetpath):
    """Extract the TarInfo object tarinfo to a physical
      file called targetpath.
    """
    # Fetch the TarInfo object for the given name
    # and build the destination pathname, replacing
    # forward slashes to platform specific separators.
    targetpath = targetpath.rstrip("/")
    targetpath = targetpath.replace("/", os.sep)

    # Create all upper directories.
    upperdirs = os.path.dirname(targetpath)
    if upperdirs and not os.path.exists(upperdirs):
      # Create directories that are not part of the archive with
      # default permissions.
      os.makedirs(upperdirs)

    if tarinfo.islnk() or tarinfo.issym():
      self._dbg(1, "%s -> %s" % (tarinfo.name, tarinfo.linkname))
    else:
      self._dbg(1, tarinfo.name)

    if tarinfo.isreg():
      self.makefile(tarinfo, targetpath)
    elif tarinfo.isdir():
      self.makedir(tarinfo, targetpath)
    elif tarinfo.isfifo():
      self.makefifo(tarinfo, targetpath)
    elif tarinfo.ischr() or tarinfo.isblk():
      self.makedev(tarinfo, targetpath)
    elif tarinfo.islnk() or tarinfo.issym():
      self.makelink(tarinfo, targetpath)
    elif tarinfo.type not in SUPPORTED_TYPES:
      self.makeunknown(tarinfo, targetpath)
    else:
      self.makefile(tarinfo, targetpath)

    self.chown(tarinfo, targetpath)
    if not tarinfo.issym():
      self.chmod(tarinfo, targetpath)
      self.utime(tarinfo, targetpath)

  #--------------------------------------------------------------------------
  # Below are the different file methods. They are called via
  # _extract_member() when extract() is called. They can be replaced in a
  # subclass to implement other functionality.

  def makedir(self, tarinfo, targetpath):
    """Make a directory called targetpath.
    """
    try:
      # Use a safe mode for the directory, the real mode is set
      # later in _extract_member().
      os.mkdir(targetpath, 0700)
    except EnvironmentError, e:
      if e.errno != errno.EEXIST:
        raise

  def makefile(self, tarinfo, targetpath):
    """Make a file called targetpath.
    """
    source = self.extractfile(tarinfo)
    try:
      with bltn_open(targetpath, "wb") as target:
        copyfileobj(source, target)
    finally:
      source.close()

  def makeunknown(self, tarinfo, targetpath):
    """Make a file from a TarInfo object with an unknown type
      at targetpath.
    """
    self.makefile(tarinfo, targetpath)
    self._dbg(1, "tarfile: Unknown file type %r, " \
           "extracted as regular file." % tarinfo.type)

  def makefifo(self, tarinfo, targetpath):
    """Make a fifo called targetpath.
    """
    if hasattr(os, "mkfifo"):
      os.mkfifo(targetpath)
    else:
      raise ExtractError("fifo not supported by system")

  def makedev(self, tarinfo, targetpath):
    """Make a character or block device called targetpath.
    """
    if not hasattr(os, "mknod") or not hasattr(os, "makedev"):
      raise ExtractError("special devices not supported by system")

    mode = tarinfo.mode
    if tarinfo.isblk():
      mode |= stat.S_IFBLK
    else:
      mode |= stat.S_IFCHR

    os.mknod(targetpath, mode,
         os.makedev(tarinfo.devmajor, tarinfo.devminor))

  def makelink(self, tarinfo, targetpath):
    """Make a (symbolic) link called targetpath. If it cannot be created
     (platform limitation), we try to make a copy of the referenced file
     instead of a link.
    """
    if hasattr(os, "symlink") and hasattr(os, "link"):
      # For systems that support symbolic and hard links.
      if tarinfo.issym():
        if os.path.lexists(targetpath):
          os.unlink(targetpath)
        os.symlink(tarinfo.linkname, targetpath)
      else:
        # See extract().
        if os.path.exists(tarinfo._link_target):
          if os.path.lexists(targetpath):
            os.unlink(targetpath)
          os.link(tarinfo._link_target, targetpath)
        else:
          self._extract_member(self._find_link_target(tarinfo), targetpath)
    else:
      try:
        self._extract_member(self._find_link_target(tarinfo), targetpath)
      except KeyError:
        raise ExtractError("unable to resolve link inside archive")

  def chown(self, tarinfo, targetpath):
    """Set owner of targetpath according to tarinfo.
    """
    if pwd and hasattr(os, "geteuid") and os.geteuid() == 0:
      # We have to be root to do so.
      try:
        g = grp.getgrnam(tarinfo.gname)[2]
      except KeyError:
        g = tarinfo.gid
      try:
        u = pwd.getpwnam(tarinfo.uname)[2]
      except KeyError:
        u = tarinfo.uid
      try:
        if tarinfo.issym() and hasattr(os, "lchown"):
          os.lchown(targetpath, u, g)
        else:
          if sys.platform != "os2emx":
            os.chown(targetpath, u, g)
      except EnvironmentError, e:
        raise ExtractError("could not change owner")

  def chmod(self, tarinfo, targetpath):
    """Set file permissions of targetpath according to tarinfo.
    """
    if hasattr(os, 'chmod'):
      try:
        os.chmod(targetpath, tarinfo.mode)
      except EnvironmentError, e:
        raise ExtractError("could not change mode")

  def utime(self, tarinfo, targetpath):
    """Set modification time of targetpath according to tarinfo.
    """
    if not hasattr(os, 'utime'):
      return
    try:
      os.utime(targetpath, (tarinfo.mtime, tarinfo.mtime))
    except EnvironmentError, e:
      raise ExtractError("could not change modification time")

  #--------------------------------------------------------------------------
  def next(self):
    """Return the next member of the archive as a TarInfo object, when
      TarFile is opened for reading. Return None if there is no more
      available.
    """
    self._check("ra")
    if self.firstmember is not None:
      m = self.firstmember
      self.firstmember = None
      return m

    # Read the next block.
    self.fileobj.seek(self.offset)
    tarinfo = None
    while True:
      try:
        tarinfo = self.tarinfo.fromtarfile(self)
      except EOFHeaderError, e:
        if self.ignore_zeros:
          self._dbg(2, "0x%X: %s" % (self.offset, e))
          self.offset += BLOCKSIZE
          continue
      except InvalidHeaderError, e:
        if self.ignore_zeros:
          self._dbg(2, "0x%X: %s" % (self.offset, e))
          self.offset += BLOCKSIZE
          continue
        elif self.offset == 0:
          raise ReadError(str(e))
      except EmptyHeaderError:
        if self.offset == 0:
          raise ReadError("empty file")
      except TruncatedHeaderError, e:
        if self.offset == 0:
          raise ReadError(str(e))
      except SubsequentHeaderError, e:
        raise ReadError(str(e))
      break

    if tarinfo is not None:
      self.members.append(tarinfo)
    else:
      self._loaded = True

    return tarinfo

  #--------------------------------------------------------------------------
  # Little helper methods:

  def _getmember(self, name, tarinfo=None, normalize=False):
    """Find an archive member by name from bottom to top.
      If tarinfo is given, it is used as the starting point.
    """
    # Ensure that all members have been loaded.
    members = self.getmembers()

    # Limit the member search list up to tarinfo.
    if tarinfo is not None:
      members = members[:members.index(tarinfo)]

    if normalize:
      name = os.path.normpath(name)

    for member in reversed(members):
      if normalize:
        member_name = os.path.normpath(member.name)
      else:
        member_name = member.name

      if name == member_name:
        return member

  def _load(self):
    """Read through the entire archive file and look for readable
      members.
    """
    while True:
      tarinfo = self.next()
      if tarinfo is None:
        break
    self._loaded = True

  def _check(self, mode=None):
    """Check if TarFile is still open, and if the operation's mode
      corresponds to TarFile's mode.
    """
    if self.closed:
      raise IOError("%s is closed" % self.__class__.__name__)
    if mode is not None and self.mode not in mode:
      raise IOError("bad operation for mode %r" % self.mode)

  def _find_link_target(self, tarinfo):
    """Find the target member of a symlink or hardlink member in the
      archive.
    """
    if tarinfo.issym():
      # Always search the entire archive.
      linkname = "/".join(filter(None, (os.path.dirname(tarinfo.name), tarinfo.linkname)))
      limit = None
    else:
      # Search the archive before the link, because a hard link is
      # just a reference to an already archived file.
      linkname = tarinfo.linkname
      limit = tarinfo

    member = self._getmember(linkname, tarinfo=limit, normalize=True)
    if member is None:
      raise KeyError("linkname %r not found" % linkname)
    return member

  def __iter__(self):
    """Provide an iterator object.
    """
    if self._loaded:
      return iter(self.members)
    else:
      return TarIter(self)

  def _dbg(self, level, msg):
    """Write debugging output to sys.stderr.
    """
    if level <= self.debug:
      print >> sys.stderr, msg

  def __enter__(self):
    self._check()
    return self

  def __exit__(self, type, value, traceback):
    if type is None:
      self.close()
    else:
      # An exception occurred. We must not call close() because
      # it would try to write end-of-archive blocks and padding.
      if not self._extfileobj:
        self.fileobj.close()
      self.closed = True
# class TarFile

TarFile

TarFile 源碼

TarFile 源碼

(6)json 和 pickle模塊:文件只能存二進(jìn)制或字符串,不能存其他類型,所以用到了用于序列化的兩個模塊

(7)shelve模塊:shelve模塊內(nèi)部對pickle進(jìn)行了封裝,shelve模塊是一個簡單的k,v將內(nèi)存數(shù)據(jù)通過文件持久化的模塊,可以持久化任何pickle可支持的python數(shù)據(jù)格式 (可以存儲數(shù)據(jù)、獲取數(shù)據(jù)、給數(shù)據(jù)重新賦值)

#!/usr/bin/env python
# -*- coding:utf-8 -*-
#-Author-solo
import shelve
# k,v方式存儲數(shù)據(jù)
s = shelve.open("shelve_test") # 打開一個文件
tuple = (1, 2, 3, 4)
list = ['a', 'b', 'c', 'd']
info = {"name": "lzl", "age": 18}
s["tuple"] = tuple # 持久化元組
s["list"] = list
s["info"] = info
s.close()
# 通過key獲取value值
d = shelve.open("shelve_test") # 打開一個文件
print(d["tuple"]) # 讀取
print(d.get("list"))
print(d.get("info"))
# (1, 2, 3, 4)
# ['a', 'b', 'c', 'd']
# {'name': 'lzl', 'age': 18}
d.close()
# 循環(huán)打印key值
s = shelve.open("shelve_test") # 打開一個文件
for k in s.keys():       # 循環(huán)key值
  print(k)
# list
# tuple
# info
s.close()
# 更新key的value值
s = shelve.open("shelve_test") # 打開一個文件
s.update({"list":[22,33]})   #重新賦值或者s["list"] = [22,33]
print(s["list"])
#[22, 33]
s.close()

(8)xml模塊:xml是實(shí)現(xiàn)不同語言或程序之間進(jìn)行數(shù)據(jù)交換的協(xié)議,跟json差不多,但json使用起來更簡單(通過<>節(jié)點(diǎn)來區(qū)別數(shù)據(jù)結(jié)構(gòu))

<?xml version="1.0"?><data>
  <country name="Liechtenstein">
    <rank updated="yes">2</rank>
    <year>2008</year>
    <gdppc>141100</gdppc>
    <neighbor name="Austria" direction="E"/>
    <neighbor name="Switzerland" direction="W"/>
  </country>
  <country name="Singapore">
    <rank updated="yes">5</rank>
    <year>2011</year>
    <gdppc>59900</gdppc>
    <neighbor name="Malaysia" direction="N"/>
  </country>
  <country name="Panama">
    <rank updated="yes">69</rank>
    <year>2011</year>
    <gdppc>13600</gdppc>
    <neighbor name="Costa Rica" direction="W"/>
    <neighbor name="Colombia" direction="E"/>
  </country></data>

文件
import xml.etree.ElementTree as ET
tree = ET.parse("xmltest.xml")
root = tree.getroot()
print(root.tag)
#遍歷xml文檔
for child in root:
  print(child.tag, child.attrib)
  for i in child:
    print(i.tag,i.text)
#只遍歷year 節(jié)點(diǎn)
for node in root.iter('year'):
  print(node.tag,node.text)
#修改
for node in root.iter('year'):
  new_year = int(node.text) + 1
  node.text = str(new_year)
  node.set("updated","yes")
tree.write("xmltest.xml")
#刪除node
for country in root.findall('country'):
  rank = int(country.find('rank').text)
  if rank > 50:
   root.remove(country)
tree.write('output.xml')

###########自己創(chuàng)建xml文檔
import xml.etree.ElementTree as ET 
new_xml = ET.Element("namelist")
name = ET.SubElement(new_xml,"name",attrib={"enrolled":"yes"})
age = ET.SubElement(name,"age",attrib={"checked":"no"})
sex = ET.SubElement(name,"sex")
sex.text = '33'
name2 = ET.SubElement(new_xml,"name",attrib={"enrolled":"no"})
age = ET.SubElement(name2,"age")
age.text = '19'
et = ET.ElementTree(new_xml) #生成文檔對象
et.write("test.xml", encoding="utf-8",xml_declaration=True)
ET.dump(new_xml) #打印生成的格式

操作

(9)configparser模塊:用于生成和修改配置文檔(很少在程序中修改配置文件)

(10)hashlib模塊:用于加密相關(guān)的操作,3.x里代替了md5模塊和sha模塊,主要提供 SHA1, SHA224, SHA256, SHA384, SHA512 ,MD5 算法

import hashlib
m = hashlib.md5()
m.update(b"Hello")
m.update(b"It's me")
print(m.digest())
m.update(b"It's been a long time since last time we ...")
print(m.digest()) #2進(jìn)制格式hash
print(len(m.hexdigest())) #16進(jìn)制格式hash
'''
def digest(self, *args, **kwargs): # real signature unknown
  """ Return the digest value as a string of binary data. """
  pass
def hexdigest(self, *args, **kwargs): # real signature unknown
  """ Return the digest value as a string of hexadecimal digits. """
  pass
'''
import hashlib 
# ######## md5 ########
hash = hashlib.md5()
hash.update('admin')
print(hash.hexdigest())
# ######## sha1 ########
hash = hashlib.sha1()
hash.update('admin')
print(hash.hexdigest())
# ######## sha256 ########
hash = hashlib.sha256()
hash.update('admin')
print(hash.hexdigest())
# ######## sha384 ########
hash = hashlib.sha384()
hash.update('admin')
print(hash.hexdigest())
# ######## sha512 ########
hash = hashlib.sha512()
hash.update('admin')
print(hash.hexdigest())

hashlib
import hmac
h = hmac.new('wueiqi')
h.update('hellowo')
print h.hexdigest()

(11)re模塊:用于對python的正則表達(dá)式的操作;匹配(動態(tài)模糊的匹配);關(guān)鍵是匹配條件

'.'   默認(rèn)匹配除\n之外的任意一個字符,若指定flag DOTALL,則匹配任意字符,包括換行
'^'   匹配字符開頭,若指定flags MULTILINE,這種也可以匹配上(r"^a","\nabc\neee",flags=re.MULTILINE)
'$'   匹配字符結(jié)尾,或e.search("foo$","bfoo\nsdfsf",flags=re.MULTILINE).group()也可以
'*'   匹配*號前的字符0次或多次,re.findall("ab*","cabb3abcbbac") 結(jié)果為['abb', 'ab', 'a']
'+'   匹配前一個字符1次或多次,re.findall("ab+","ab+cd+abb+bba") 結(jié)果['ab', 'abb']
'?'   匹配前一個字符1次或0次
'{m}'  匹配前一個字符m次
'{n,m}' 匹配前一個字符n到m次,re.findall("ab{1,3}","abb abc abbcbbb") 結(jié)果'abb', 'ab', 'abb']
'|'   匹配|左或|右的字符,re.search("abc|ABC","ABCBabcCD").group() 結(jié)果'ABC'
'(...)' 分組匹配,re.search("(abc){2}a(123|456)c", "abcabca456c").group() 結(jié)果 abcabca456c
'[a-z]' 匹配a到z任意一個字符
'[^()]' 匹配除()以外的任意一個字符 
'\A'  只從字符開頭匹配,re.search("\Aabc","alexabc") 是匹配不到的
'\Z'  匹配字符結(jié)尾,同$
'\d'  匹配數(shù)字0-9
'\D'  匹配非數(shù)字
'\w'  匹配[A-Za-z0-9]
'\W'  匹配非[A-Za-z0-9]
'\s'  匹配空白字符、\t、\n、\r , re.search("\s+","ab\tc1\n3").group() 結(jié)果 '\t' 
'(?P<name>...)' 分組匹配 re.search("(?P<province>[0-9]{4})(?P<city>[0-9]{2})(?P<birthday>[0-9]{4})","371481199306143242").groupdict("city")
結(jié)果{'province': '3714', 'city': '81', 'birthday': '1993'}

正則表達(dá)式

①、match:從起始位置開始去匹配

#match
import re               
obj = re.match('\d+', '123uua123sf')    #從第一個字符開始匹配一個到多個數(shù)字
print(obj)                
#<_sre.SRE_Match object; span=(0, 3), match='123'>
if obj:                  #如果有匹配到字符則執(zhí)行,為空不執(zhí)行
  print(obj.group())          #打印匹配到的內(nèi)容
#123

②、search:最前面去匹配(不一定是最開始位置),匹配最前

#search
import re
obj = re.search('\d+', 'a123uu234asf')   #從數(shù)字開始匹配一個到多個數(shù)字
print(obj)
#<_sre.SRE_Match object; span=(1, 4), match='123'>
if obj:                  #如果有匹配到字符則執(zhí)行,為空不執(zhí)行
  print(obj.group())          #打印匹配到的內(nèi)容
#123
import re
obj = re.search('\([^()]+\)', 'sdds(a1fwewe2(3uusfdsf2)34as)f')   #匹配最里面()的內(nèi)容
print(obj)
#<_sre.SRE_Match object; span=(13, 24), match='(3uusfdsf2)'>
if obj:                  #如果有匹配到字符則執(zhí)行,為空不執(zhí)行
  print(obj.group())          #打印匹配到的內(nèi)容
#(3uusfdsf2)

③、group與groups的區(qū)別

#group與groups的區(qū)別
import re
a = "123abc456"
b = re.search("([0-9]*)([a-z]*)([0-9]*)", a)
print(b)
#<_sre.SRE_Match object; span=(0, 9), match='123abc456'>
print(b.group())
#123abc456
print(b.group(0))
#123abc456
print(b.group(1))
#123
print(b.group(2))
#abc
print(b.group(3))
#456
print(b.groups())
#('123', 'abc', '456')

④、findall上述兩中方式均用于匹配單值,即:只能匹配字符串中的一個,如果想要匹配到字符串中所有符合條件的元素,則需要使用 findall;findall沒有g(shù)roup 用法

#findall
import re
obj = re.findall('\d+', 'a123uu234asf')   #匹配多個
if obj:                  #如果有匹配到字符則執(zhí)行,為空不執(zhí)行
  print(obj)               #生成的內(nèi)容為列表
#['123', '234']

⑤、sub:用于替換匹配的字符串

#sub
import re
content = "123abc456"
new_content = re.sub('\d+', 'ABC', content)
print(new_content)
#ABCabcABC

⑥、split:根據(jù)指定匹配進(jìn)行分組(分割)

#split
import re
content = "1 - 2 * ((60-30+1*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2) )"
new_content = re.split('\*', content)    #用*進(jìn)行分割,分割為列表
print(new_content)
#['1 - 2 ', ' ((60-30+1', '(9-2', '5/3+7/3', '99/4', '2998+10', '568/14))-(-4', '3)/(16-3', '2) )'] 
content = "'1 - 2 * ((60-30+1*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2) )'"
new_content = re.split('[\+\-\*\/]+', content)
# new_content = re.split('\*', content, 1)
print(new_content)
#["'1 ", ' 2 ', ' ((60', '30', '1', '(9', '2', '5', '3', '7', '3', '99', '4', '2998', '10', '568', '14))',
# '(', '4', '3)', '(16', '3', "2) )'"]
inpp = '1-2*((60-30 +(-40-5)*(9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2))'
inpp = re.sub('\s*','',inpp)        #把空白字符去掉
print(inpp)
new_content = re.split('\(([\+\-\*\/]?\d+[\+\-\*\/]?\d+){1}\)', inpp, 1)
print(new_content)
#['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的功能(利用程序去執(zhí)行各種HTTP請求。如果要模擬瀏覽器完成特定功能,需要把請求偽裝成瀏覽器。偽裝的方法是先監(jiān)控瀏覽器發(fā)出的請求,再根據(jù)瀏覽器的請求頭來偽裝,User-Agent頭就是用來標(biāo)識瀏覽器的。)

#!/usr/bin/env python
# -*- coding:utf-8 -*-
#-Author-solo
import urllib.request
def getdata():
  url = "http://www.baidu.com"
  data = urllib.request.urlopen(url).read()
  data = data.decode("utf-8")
  print(data)
getdata()

###urlopen返回的類文件對象支持close、read、readline、和readlines方法

 

十二、面向?qū)ο?/p>

面向過程編程:通過代碼的層層堆積來實(shí)現(xiàn)功能。不易迭代和維護(hù)。
函數(shù)式編程:將某功能代碼封裝到函數(shù)中,僅調(diào)用函數(shù)即可
面向?qū)ο缶幊蹋豪谩邦悺焙汀皩ο蟆眮韯?chuàng)建各種模型來實(shí)現(xiàn)對真實(shí)世界的描述;使用面向?qū)ο缶幊痰脑蛞环矫媸且驗樗梢允钩绦虻木S護(hù)和擴(kuò)展變得更簡單,并且可以大大提高程序開發(fā)效率 ,另外,基于面向?qū)ο蟮某绦蚩梢允顾烁尤菀桌斫饽愕拇a邏輯,從而使團(tuán)隊開發(fā)變得更從容。

#經(jīng)典類
class A():
  def __init__(self):
    print("A")
class B(A):
  pass
class C(A):
  def __init__(self):
    print("C")
class D(B,C):
  pass
obj = D()
#A
#新式類
class A(object):
  def __init__(self):
    print("A")
class B(A):
  pass
class C(A):
  def __init__(self):
    print("C")
class D(B,C):
  pass
obj = D()
#C

經(jīng)典類、新式類

#屬性方法
class Flight(object):
  def __init__(self, name):
    self.flight_name = name
  def checking_status(self):
    print("checking flight %s status " % self.flight_name)
    return 1
  @property
  def flight_status(self):
    status = self.checking_status()
    if status == 0:
      print("flight got canceled...")
    elif status == 1:
      print("flight is arrived...")
    elif status == 2:
      print("flight has departured already...")
    else:
      print("cannot confirm the flight status...,please check later")
  @flight_status.setter # 修改   執(zhí)行修改操作時觸發(fā)
  def flight_status(self, status):
    status_dic = {
    0: "canceled",
    1:"arrived",
    2: "departured"
    }
    print("\033[31;1mHas changed the flight status to \033[0m", status_dic.get(status))
  @flight_status.deleter # 刪除
  def flight_status(self):
    print("status got removed...")
f = Flight("CA980")
f.flight_status = 0 # 觸發(fā)@flight_status.setter 只執(zhí)行setter裝飾的代碼
del f.flight_status # 觸發(fā)@flight_status.deleter 只執(zhí)行deleter裝飾的代碼

#執(zhí)行相應(yīng)的操作,觸發(fā)相應(yīng)的裝飾器,此時不會再觸發(fā)原來的屬性,只執(zhí)行裝飾器下面的代碼,需要做相應(yīng)的操作可在代碼塊里添加(修改,刪除);只是觸發(fā)了而已,裝飾器并沒有做什么操作

航班查詢

類的特殊成員方法:
① __doc__  表示類的描述信息

#__doc__
class Foo:
  """ 描述類信息,這是用于看片的神奇 """
  def func(self):
    pass
print(Foo.__doc__)
# 描述類信息,這是用于看片的神奇

② __module__ 和 __class__
__module__ 表示當(dāng)前操作的對象在哪個模塊
__class__ 表示當(dāng)前操作的對象的類是什么

# __module__ 和 __class__
class Foo:
  """ 描述類信息,這是用于看片的神奇 """
  def func(self):
    pass
A = Foo()
print(A.__module__)
print(A.__class__)
# __main__
# <class '__main__.Foo'>

③ __init__ 構(gòu)造方法,通過類創(chuàng)建對象時,自動觸發(fā)執(zhí)行

④ __del__析構(gòu)方法,當(dāng)對象在內(nèi)存中被釋放時,自動觸發(fā)執(zhí)行

⑤ __call__ 對象后面加括號,觸發(fā)執(zhí)行
注:__init__的執(zhí)行是由創(chuàng)建對象觸發(fā)的,即:對象 = 類名() ;而對于 __call__ 方法的執(zhí)行是由對象后加括號觸發(fā)的,即:對象() 或者 類()()

# __call__
class Foo:
  def __init__(self):
    pass
  def __call__(self, *args, **kwargs):
    print('__call__')
obj = Foo() # 執(zhí)行 __init__
obj() # 執(zhí)行 __call__
#__call__

⑥ __dict__ 查看類或?qū)ο笾械乃谐蓡T

class Province:
  country = 'China'
  def __init__(self, name, count):
    self.name = name
    self.count = count
  def func(self, *args, **kwargs):
    print('func')
# 獲取類的成員,即:靜態(tài)字段、方法、
print(Province.__dict__)
# 輸出:{'__init__': <function Province.__init__ at 0x0054D588>, '__dict__': <attribute '__dict__' of 'Province' objects>,
# '__doc__': None, 'func': <function Province.func at 0x0054D4B0>, '__weakref__': <attribute '__weakref__' of 'Province' objects>,
# 'country': 'China', '__module__': '__main__'}
obj1 = Province('HeBei', 10000)
print(obj1.__dict__)
# 獲取 對象obj1 的成員
# 輸出:{'count': 10000, 'name': 'HeBei'}

⑦ __str__ 如果一個類中定義了__str__方法,那么在打印 對象 時,默認(rèn)輸出該方法的返回值

#__str__
class Foo:
  def __str__(self):
    return 'solo'
obj = Foo()
print(obj)       #輸出__str__返回值 而不是內(nèi)存地址
# 輸出:solo

⑧ __getitem__、__setitem__、__delitem__
用于索引操作,如字典。以上分別表示獲取、設(shè)置、刪除數(shù)據(jù)

#__getitem__、__setitem__、__delitem__
class Foo(object):
  def __getitem__(self, key):
    print('__getitem__', key)
  def __setitem__(self, key, value):
    print('__setitem__', key, value)
  def __delitem__(self, key):
    print('__delitem__', key)
obj = Foo()
result = obj['k1'] # 自動觸發(fā)執(zhí)行 __getitem__
obj['k2'] = 'solo' # 自動觸發(fā)執(zhí)行 __setitem__
del obj['k1']
# __getitem__ k1
# __setitem__ k2 solo
# __delitem__ k1

⑨ __new__ \ __metaclass__

 print type(f) # 輸出:<class '__main__.Foo'>       表示,obj 對象由Foo類創(chuàng)建
2 print type(Foo) # 輸出:<type 'type'>              表示,F(xiàn)oo類對象由 type 類創(chuàng)建

f對象是Foo類的一個實(shí)例,F(xiàn)oo類對象是 type 類的一個實(shí)例,即:Foo類對象 是通過type類的構(gòu)造方法創(chuàng)建

是由 type 類實(shí)例化產(chǎn)生那么問題來了,類默認(rèn)是由 type 類實(shí)例化產(chǎn)生,type類中如何實(shí)現(xiàn)的創(chuàng)建類?類又是如何創(chuàng)建對象?
答:類中有一個屬性 __metaclass__,其用來表示該類由 誰 來實(shí)例化創(chuàng)建,所以,我們可以為 __metaclass__ 設(shè)置一個type類的派生類,從而查看 類 創(chuàng)建的過程

class MyType(type):
  def __init__(self, what, bases=None, dict=None):
    print("--MyType init---")
    super(MyType, self).__init__(what, bases, dict)
  def __call__(self, *args, **kwargs):
    print("--MyType call---")
    obj = self.__new__(self, *args, **kwargs)
    self.__init__(obj, *args, **kwargs)
class Foo(object):
  __metaclass__ = MyType
  def __init__(self, name):
    self.name = name
    print("Foo ---init__")
  def __new__(cls, *args, **kwargs):
    print("Foo --new--")
    return object.__new__(cls)
# 第一階段:解釋器從上到下執(zhí)行代碼創(chuàng)建Foo類
# 第二階段:通過Foo類創(chuàng)建obj對象
obj = Foo("solo")

反射:通過字符串映射或修改程序運(yùn)行時的狀態(tài)、屬性、方法。 有以下4個方法
① hasattr(obj,str) 判斷一個對象obj里是否有對應(yīng)的str字符串的方法
② getattr(obj,str) 根據(jù)字符串去獲取obj對象里的對應(yīng)的方法的內(nèi)存地址

class Foo(object):
  def __init__(self,name):
    self.name = name
  def func(self):
    print("func",self.name)
obj = Foo("alex")
str = "func"
print(hasattr(obj,str))  # 檢查是否含有成員 有沒有obj.str屬性
if hasattr(obj,str):
  getattr(obj,str)()   #getattr(obj,str) = obj.str
# True
# func alex

③ setattr(obj,'y','z') obj.y = z 通過字符串添加屬性

def bulk(self):
  print("%s is yelling"%self.name)
class Foo(object):
  def __init__(self,name):
    self.name = name
  def func(self):
    print("func",self.name)
obj = Foo("alex")
str = "talk"
print(hasattr(obj,str))  # 檢查是否含有成員 有沒有obj.str屬性
if hasattr(obj,str):
  getattr(obj,str)()   # getattr(obj,str) = obj.str
else:
  setattr(obj,str,bulk)  # setattr(obj,str,bulk 相當(dāng)于 obj.str = bulk
  getattr(obj,str)()
# False
# alex is yelling

④ delattr(obj,str) 刪除obj.str 通過字符串刪除屬性

class Foo(object):
  def __init__(self,name):
    self.name = name
  def func(self):
    print("func",self.name)
obj = Foo("alex")
str = "name"
if hasattr(obj,str):
  delattr(obj,str)   # 刪除屬性obj.str
print(obj.name)
# Traceback (most recent call last):
#  File "C:/Users/L/PycharmProjects/s14/preview/Day7/main.py", line 40, in <module>
#   print(obj.name)
# AttributeError: 'Foo' object has no attribute 'name'

相關(guān)文章

  • python人工智能tensorflow函數(shù)tf.assign使用方法

    python人工智能tensorflow函數(shù)tf.assign使用方法

    這篇文章主要為大家介紹了python人工智能tensorflow函數(shù)tf.assign使用方法,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-05-05
  • python自動化之如何利用allure生成測試報告

    python自動化之如何利用allure生成測試報告

    這篇文章主要給大家介紹了關(guān)于python自動化之如何利用allure生成測試報告的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-05-05
  • python matplotlib模塊基本圖形繪制方法小結(jié)【直線,曲線,直方圖,餅圖等】

    python matplotlib模塊基本圖形繪制方法小結(jié)【直線,曲線,直方圖,餅圖等】

    這篇文章主要介紹了python matplotlib模塊基本圖形繪制方法,結(jié)合實(shí)例形式總結(jié)分析了Python使用matplotlib模塊繪制直線,曲線,直方圖,餅圖等圖形的相關(guān)操作技巧,需要的朋友可以參考下
    2020-04-04
  • Python元組的定義及使用

    Python元組的定義及使用

    這篇文章主要介紹了Python元組的定義及使用,在Python中元組是一個和列表非常類似的數(shù)據(jù)類型,不同之處就是列表中的元素可以修改,而元組之中的元素不可以修改。想具體了解的下小伙伴請參考下面文章的具體內(nèi)容,希望對你有所幫助
    2021-11-11
  • Python中jieba庫的使用方法

    Python中jieba庫的使用方法

    jieba庫是一款優(yōu)秀的 Python 第三方中文分詞庫,本文主要介紹了Python中jieba庫的使用方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-06-06
  • Python中g(shù)etattr函數(shù)和hasattr函數(shù)作用詳解

    Python中g(shù)etattr函數(shù)和hasattr函數(shù)作用詳解

    這篇文章主要介紹了Python中g(shù)etattr函數(shù)和hasattr函數(shù)作用的相關(guān)知識,非常不錯具有參考借鑒價值,需要的朋友可以參考下
    2016-06-06
  • python3訪問字典里的值實(shí)例方法

    python3訪問字典里的值實(shí)例方法

    在本篇內(nèi)容里小編給大家整理的是一篇關(guān)于python3訪問字典里的值實(shí)例方法,有興趣的朋友們可以學(xué)習(xí)參考下。
    2020-11-11
  • 手動安裝Anaconda環(huán)境變量的實(shí)現(xiàn)教程

    手動安裝Anaconda環(huán)境變量的實(shí)現(xiàn)教程

    這篇文章主要介紹了手動安裝Anaconda環(huán)境變量的實(shí)現(xiàn)教程,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-01-01
  • python3.6、opencv安裝環(huán)境搭建過程(圖文教程)

    python3.6、opencv安裝環(huán)境搭建過程(圖文教程)

    這篇文章主要介紹了python3.6、opencv安裝環(huán)境搭建,本文圖文并茂給大家介紹的非常詳細(xì),具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-11-11
  • Keras 中Leaky ReLU等高級激活函數(shù)的用法

    Keras 中Leaky ReLU等高級激活函數(shù)的用法

    這篇文章主要介紹了Keras 中Leaky ReLU等高級激活函數(shù)的用法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-07-07

最新評論