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

Python基礎語言學習筆記總結(精華)

 更新時間:2017年11月14日 11:58:05   作者:李小小小偉  
給大家分享一篇關于Python基礎學習內容的學習筆記整理總結篇,里面匯集了學習Python基礎語言的難點和技巧,分享給大家。

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

一、變量賦值及命名規(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、變量名只能是 字母、數字或下劃線的任意組合
2、變量名的第一個字符不能是數字
3、以下關鍵字不能聲明為變量名['and', 'as', 'assert', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'exec', 'finally', 'for', 'from', 'global','if', 'import', 'in', 'is', 'lambda', 'not', 'or', 'pass', 'print', 'raise', 'return', 'try', 'while', 'with', 'yield']

二、字符編碼

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

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

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

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

 擴展:字符編碼和轉碼,bytes和str區(qū)別

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

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

#!/usr/bin/env python
# -*- coding:utf-8 -*-
#-Author-solo
msg = "里約奧運"
print(msg.encode("utf-8"))           #如果不指定編碼格式,默認為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"))
#里約奧運

為什么要進行編碼和轉碼?

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

① Python3.0進行編碼轉換(默認Unicode編碼)

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

② Python2.0中的編碼轉換(默認ascii編碼)

① 聲明字符編碼(utf-8)
# -*- coding:utf-8 -*-
name = "李偉"          #ascii碼里是沒有字符“你好”的,此時的name為uft-8
name1 = name.decode("utf-8")  #UTF-8轉為Unicode
name2 = name1.encode("gbk")   #Unicode轉為gbk
② 使用默認字符編碼(ascii)
name = "nihao"       #英文字符,且第二行字符聲明去掉,此刻name為ascii碼
name1 = name.decode("ascii")   #ascii碼轉為unicode
name2 = name1.encode("utf-8") #unicode轉為utf-8
name3 =name1.encode("gbk")   #unicode轉為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強制轉換為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檢測數據類型為字符串,%d檢測數據類型為整數,%f檢測數據類型為浮點數 強制
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、+ :每增加一個一個+就會開辟一塊新的內存空間
3、.fomat :不會出現上述問題,有時使用為了兼容Python2版本。如使用logging庫

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

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


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


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


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


五、基本數據類型

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

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

更多功能:

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): 
    """ 返回表示該數字的時占用的最少位數 """
    """
    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
    """ 返回該復數的共軛復數 """
    """ 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): 
    """ 比較兩個數大小 """
    """ x.__cmp__(y) <==> cmp(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 __float__(self): 
    """ 轉換為浮點類型 """ 
    """ 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
    """ 內部調用 __new__方法或創(chuàng)建對象時傳入參數使用 """ 
    pass

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

  def __hex__(self): 
    """ 返回當前數的 十六進制 表示 """ 
    """ x.__hex__() <==> hex(x) """
    pass

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

  def __init__(self, x, base=10): # known special case of int.__init__
    """ 構造方法,執(zhí)行 x = 123 或 x = int(10) 時,自動調用,暫時忽略 """ 
    """
    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): 
    """ 轉換為整數 """ 
    """ x.__int__() <==> int(x) """
    pass

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

  def __long__(self): 
    """ 轉換為長整數 """ 
    """ 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): 
    """ 返回改值的 八進制 表示 """ 
    """ 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): 
    """轉化為解釋器可讀取的形式 """
    """ x.__repr__() <==> repr(x) """
    pass

  def __str__(self): 
    """轉換為人閱讀的形式,如果沒有適于人閱讀的解釋形式的話,則返回解釋器課閱讀的形式"""
    """ 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): 
    """ 返回數值被截取為整形的值,在整形中無意義 """
    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
  """ 虛數,無意義 """
  """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"""

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的長整數沒有指定位寬,即:Python沒有限制長整數數值的大小,但實際上由于機器內存有限,我們使用的長整數數值不可能無限大。自從Python2.2起,如果整數發(fā)生溢出,Python會自動將整數數據轉換為長整數,所以如今在長整數數據后面不加字母L也不會導致嚴重后果

三、浮點型
如:3.14、2.88

類型常用功能:

#浮點型功能與整形基本類似

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):  
    """ 將十六進制字符串轉換成浮點型 """
    """
    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):  
    """ 返回當前值的 16 進制表示 """
    """
    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)計字符串出現某個字符的個數
#2
print(name.center(30,"-"))     #打印30個字符,不夠的-補齊
#--------my name is solo--------
print(name.ljust(30,"-"))      #打印30個字符,不夠的-補齊,字符串在左邊
#my name is solo----------------
print(name.endswith("solo"))     #判斷字符串是否以solo結尾
#True
print(name[name.find("na"):])    #find尋找na所在的索引下標 字符串也可以切片
#name is solo
print("5.3".isdigit())       #判斷字符是否為整數
#False
print("a_1A".isidentifier())    #判斷是不是一個合法的標識符(變量名)
#True
print("+".join(["1","2","3"]))   #把join后的內容加入到前面字符串中,以+為分割符
#1+2+3
print("\nsolo".strip())       #去換行符
#solo
print("1+2+3+4".split("+"))    #以+為分隔符生成新的列表,默認不寫為空格
#['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")     #轉換 一一對應
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): 
    """ 內容居中,width:總長度;fillchar:空白處填充內容,默認無 """
    """
    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): 
    """ 子序列個數 """
    """
    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 結束 """
    """
    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轉換成空格,默認一個tab轉換成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)參數,將函數式編程時細說 """
    """
    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): 
    """ 是否是字母和數字 """
    """
    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): 
    """ 是否是數字 """
    """
    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): 
    """ 內容左對齊,右側填充 """
    """
    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): 
    """ 移除左側空白 """
    """
    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): 
    """ 根據換行分割 """
    """
    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): 
    """
    轉換,需要先做一個對應表,最后一個表示刪除字符集合
    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])    #取下標0至下標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,下標有正有負時,正數在前負數在后
#['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"加到下標3的位置
print(name_list)

④ 修改

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

⑤ 刪除

#3種刪除方式
name_list = ["Alex","Tenglan","Eric","Rain","Tom","Amy"]
del name_list[3]           #del刪除,指定要刪除的下標
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']

⑥ 擴展

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

⑦ 拷貝

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

⑧ 統(tǒng)計

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

⑨ 排序和翻轉

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

⑩ 獲取下標

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

六、元組

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

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

#5種創(chuàng)建方式
age = 11,22,33,44,55      #直接寫數字或者字符串,默認創(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)建的元組,隨機排列 沒卵用
#輸出: (33, 11, 44, 22, 55)

2、元組類常用功能:

##count        #統(tǒng)計元組字符出現的次數   
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 的數據類型,也稱鍵值對。字典dict是無序的,key值必須是唯一的,不能有重復。循環(huá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"     #有相應的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()               #隨機刪除,沒卵用
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": ["很多免費的,世界最大的","質量一般"],
    "www.pornhub.com": ["很多免費的,也很大","質量比yourporn高點"],
    "letmedothistoyou.com": ["多是自拍,高質量圖片很多","資源不多,更新慢"],
    "x-art.com":["質量很高,真的很高","全部收費,屌比請繞過"]
  },
  "日韓":{
    "tokyo-hot":["質量怎樣不清楚,個人已經不喜歡日韓范了","聽說是收費的"]
  },
  "大陸":{
    "1024":["全部免費,真好,好人一生平安","服務器在國外,慢"]
  }
}
 
av_catalog["大陸"]["1024"][1] += ",可以用爬蟲爬下來"
print(av_catalog["大陸"]["1024"])
#['全部免費,真好,好人一生平安', '服務器在國外,慢,可以用爬蟲爬下來']

⑥ 循環(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)默認提取的是key
#stu1103 XiaoZe Maliya
#stu1101 TengLan Wu
#stu1102 LongZe Luola
for k,v in info_dic.items():       #先把dict生成list,數據量大的時候費時,不建議使用
  print(k,v)
#stu1103 XiaoZe Maliya
#stu1101 TengLan Wu
#stu1102 LongZe Luola

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

 

#標準創(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 隨機刪除元素
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、集合關系測試
① 交集

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}

⑥ 運算符做關系測試

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內部提供的模塊
②、業(yè)內開源的模塊
③、程序員自己開發(fā)的模塊:Python腳本的名字不要與模塊名相同

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

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

2、os模塊(與系統(tǒng)進行交互)
① os.dir、os.popen調用當前系統(tǒng)命令

3、platform模塊(識別當前運行的系統(tǒng))

七、運算符
1、算數運算:

2、比較運算:

3、賦值運算:

4、邏輯運算:

5、成員運算:

6、身份運算:

7、位運算:

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

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

import copy           #import調用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]
 
#  對變量進行修改
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           #直接賦值
對象賦值結果:solo = ["Alex", 28, ["Python", "C#", "JavaScript"]]
對象賦值時是進行對象引用(內存地址)的傳遞,被賦值的變量并沒有開辟新內存,兩個變量共用一個內存地址

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

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

import copy           #import調用copy模塊
Alex = ["Alex", 28, ["Python", "C#", "JavaScript"]]
solo = copy.copy(Alex)            #通過copy模塊里面的淺拷貝函數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]
#  對變量進行修改
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模塊里面的淺拷貝函數copy()
淺拷貝結果: solo = ["Alex", 28, ["Python", "C#", "JavaScript"]]
淺拷貝時變量solo新建了一塊內存(10201848),此內存記錄了list中元素的地址;對于list中的元素,淺拷貝會使用原始元素的引用(內存地址)

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

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

#!/usr/bin/env python
# -*- coding:utf-8 -*-
#-Author-Lian
#  深拷貝
import copy           #import調用copy模塊
 
Alex = ["Alex", 28, ["Python", "C#", "JavaScript"]]
solo = copy.deepcopy(Alex)            #通過copy模塊里面的深拷貝函數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]
 
#  對變量進行修改
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模塊里面的深拷貝函數deepcopy()
深拷貝結果: solo = ["Alex", 28, ["Python", "C#", "JavaScript"]]
深拷貝時變量solo新建了一塊內存(10201848),此內存記錄了list中元素的地址;但是,對于list中第三個元素(['Python', 'C#', 'JavaScript'])重新生成了一個地址(6203512),此時兩個變量的第三個元素的內存引用地址不同

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

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

 

九、文件操作

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

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

小結

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

十、函數

①格式

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

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

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

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

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

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

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

⑩匿名函數:不需要顯式的指定函數

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

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

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

⑫內置函數

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

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

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

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

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

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

⑰生成器:調用時才會生成相應數據的機制,稱為生成器:generator

應用:可通過yield實現在單線程的情況下實現并發(fā)運算的效果(協(xié)程)

#!/usr/bin/env python
# -*- coding:utf-8 -*-
#-Author-solo
import time
def consumer(name):
  print("%s 準備吃包子啦!" %name)
  while True:
    baozi = yield      #yield的作用:保存當前狀態(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()作用:調用yield,不給yield傳值
  print("老子開始準備做包子啦!")
  for i in range(10):
    time.sleep(1)
    print("%s做了2個包子!"%(name))
    c.send(i)        #send()作用:調用yield,給yield傳值
    c2.send(i)
producer("solo")

協(xié)程

 

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

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

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

from collections import Iterator
print(isinstance([], Iterator))
# True
小結:
1、凡是可作用于for循環(huán)的對象都是Iterable類型;
2、凡是可作用于next()函數的對象都是Iterator類型,它們表示一個惰性計算的序列;
3、集合數據類型如list、dict、str等是Iterable但不是Iterator,不過可以通過iter()函數獲得一個Iterator對象;
4、Python的for循環(huán)本質上就是通過不斷調用next()函數實現的
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

等價效果(迭代器)

十一、常用模塊

(一)、導入模塊:導入模塊的本質就是把python文件解釋一遍;導入包的本質就是把包文件下面的init.py文件運行一遍

(二)、常用模塊:

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

import time
print(time.time())       #時間戳
#1472037866.0750718
print(time.localtime())    #結構化時間
#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())      #結構化時間
#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')) #結構化時間
#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)    #表示時間間隔,即兩個時間點之間的長度
#<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模塊:生成隨機數(驗證碼)

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

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

os模塊

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

import sys
sys.argv      #命令行參數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 將文件內容拷貝到另一個文件中,可以部分內容

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里的內容拷貝到f2當中

② 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里的內容拷貝到f2當中

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

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) 拷貝文件和權限

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: 壓縮包的文件名,也可以是壓縮包的路徑。只是文件名時,則保存至當前目錄,否則保存至指定路徑,
        如:www                        =>保存至當前路徑
        如:/Users/wupeiqi/www =>保存至/Users/wupeiqi/
format: 壓縮包種類,“zip”, “tar”, “bztar”,“gztar”
root_dir: 要壓縮的文件夾路徑(默認當前目錄)
owner: 用戶,默認當前用戶
group: 組,默認當前組
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 對壓縮包的處理是調用 ZipFile 和 TarFile 兩個模塊來進行的,詳細:

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() # 可設置解壓地址
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模塊:文件只能存二進制或字符串,不能存其他類型,所以用到了用于序列化的兩個模塊

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

#!/usr/bin/env python
# -*- coding:utf-8 -*-
#-Author-solo
import shelve
# k,v方式存儲數據
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是實現不同語言或程序之間進行數據交換的協(xié)議,跟json差不多,但json使用起來更簡單(通過<>節(jié)點來區(qū)別數據結構)

<?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é)點
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模塊:用于加密相關的操作,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進制格式hash
print(len(m.hexdigest())) #16進制格式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的正則表達式的操作;匹配(動態(tài)模糊的匹配);關鍵是匹配條件

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

正則表達式

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

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

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

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

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

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

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

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

#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)    #用*進行分割,分割為列表
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ā)出的請求,再根據瀏覽器的請求頭來偽裝,User-Agent頭就是用來標識瀏覽器的。)

#!/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方法

 

十二、面向對象

面向過程編程:通過代碼的層層堆積來實現功能。不易迭代和維護。
函數式編程:將某功能代碼封裝到函數中,僅調用函數即可
面向對象編程:利用“類”和“對象”來創(chuàng)建各種模型來實現對真實世界的描述;使用面向對象編程的原因一方面是因為它可以使程序的維護和擴展變得更簡單,并且可以大大提高程序開發(fā)效率 ,另外,基于面向對象的程序可以使它人更加容易理解你的代碼邏輯,從而使團隊開發(fā)變得更從容。

#經典類
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

經典類、新式類

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

航班查詢

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

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

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

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

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

④ __del__析構方法,當對象在內存中被釋放時,自動觸發(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__ 查看類或對象中的所有成員

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__方法,那么在打印 對象 時,默認輸出該方法的返回值

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

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

#__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'>              表示,Foo類對象由 type 類創(chuàng)建

f對象是Foo類的一個實例,Foo類對象是 type 類的一個實例,即:Foo類對象 是通過type類的構造方法創(chuàng)建

是由 type 類實例化產生那么問題來了,類默認是由 type 類實例化產生,type類中如何實現的創(chuàng)建類?類又是如何創(chuàng)建對象?
答:類中有一個屬性 __metaclass__,其用來表示該類由 誰 來實例化創(chuàng)建,所以,我們可以為 __metaclass__ 設置一個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")

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

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 相當于 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'

相關文章

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

    python人工智能tensorflow函數tf.assign使用方法

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

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

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

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

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

    Python元組的定義及使用

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

    Python中jieba庫的使用方法

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

    Python中getattr函數和hasattr函數作用詳解

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

    python3訪問字典里的值實例方法

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

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

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

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

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

    Keras 中Leaky ReLU等高級激活函數的用法

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

最新評論