二. python函數與模塊

第四章.內置函數與裝飾器詳解

1.內置函數補充1

注:紅色圓圈:必會;  紫紅色方框:熟練;   綠色:瞭解node

callable()   判斷函數是否能夠被調用執行
def f1():
    pass
f1()

f2 = 123
print(callable(f1))
print(callable(f2))
###########################################################################################
# chr(), ord()  對ascii碼錶中的字符與十進制數互相轉換
r = chr(65)   # 把ascii表中十進制數轉爲字母,只能單個轉換。
print(r)
輸出結果:A
n = ord("B")   # 把ascii表中字母轉爲字母十進制數,只能單個轉換。
print(n)
輸出結果:66
###########################################################################################
#隨機驗證碼基礎知識
import random
i = random.randrange(65,91)
c = chr(i)
print(c)
輸出結果:隨機輸出一個大寫字母
---------------------------------------------------------------------------------
import random
li = []
for i in range(6):
    temp = random.randrange(65,91)  # ASCII碼錶大寫字母A-Z對應的十進制數範圍
    c = chr(temp)         # 輸出大寫字母
    li.append(c)
result = ".".join(li)
print(result)
輸出結果:隨機輸出6個大寫字母
###########################################################################################
#隨機驗證碼完整代碼
import random
li = []
for i in range(6):
    r = random.randrange(0,5)  #  0<=r<5
    if r==2 or r==4:
        num = random.randrange(0,10)
        li.append(str(num))
    else:
        temp = random.randrange(65,91)
        c = chr(temp)
        li.append(c)
result = " ".join(li)
print(result)
輸出結果:隨機生成6個大寫字母和數字的組合
###########################################################################################
# compile()  編譯單行模式
# eval()     編譯表達式模式
# exec()     編譯整個python代碼

s = "print(123)"   # 定義字符串
r = compile(s,"<string>","exec")  # 編譯字符串s轉換爲python代碼
exec(r)         # 執行編譯好的代碼
輸出結果:123
-----------------------------------------------------------------------
s = 8*8
ret = eval("s")  # 接收字符串,並將字符串做爲python表達式進行計算的功能,返回表達式運算結果
print(ret)
輸出結果:64
-----------------------------------------------------------------------
a = exec("7+8+9")   # 執行python代碼,接收代碼或字符串
b = eval("6+7+8")   # 執行表達式,而且獲取計算結果
print(a,b)
輸出結果:None 21
###########################################################################################
# dir()   快速查看對象提供哪些功能
print(dir(dict))
print(dir(list))
help(dict)
help(list)
輸出結果:
['__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'clear', 'copy', 'fromkeys', 'get', 'items', 'keys', 'pop', 'popitem', 'setdefault', 'update', 'values']
['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']
Help on class dict in module builtins:

class dict(object)
 |  dict() -> new empty dictionary
 |  dict(mapping) -> new dictionary initialized from a mapping object's
 |      (key, value) pairs
 |  dict(iterable) -> new dictionary initialized as if via:
 |      d = {}
 |      for k, v in iterable:
 |          d[k] = v
 |  dict(**kwargs) -> new dictionary initialized with the name=value pairs
 |      in the keyword argument list.  For example:  dict(one=1, two=2)
 |  
 |  Methods defined here:
 |  
 |  __contains__(self, key, /)
 |      True if D has a key k, else False.
 |  
 |  __delitem__(self, key, /)
 |      Delete self[key].
 |  
 |  __eq__(self, value, /)
 |      Return self==value.
 |  
 |  __ge__(self, value, /)
 |      Return self>=value.
 |  
 |  __getattribute__(self, name, /)
 |      Return getattr(self, name).
 |  
 |  __getitem__(...)
 |      x.__getitem__(y) <==> x[y]
 |  
 |  __gt__(self, value, /)
 |      Return self>value.
 |  
 |  __init__(self, /, *args, **kwargs)
 |      Initialize self.  See help(type(self)) for accurate signature.
 |  
 |  __iter__(self, /)
 |      Implement iter(self).
 |  
 |  __le__(self, value, /)
 |      Return self<=value.
 |  
 |  __len__(self, /)
 |      Return len(self).
 |  
 |  __lt__(self, value, /)
 |      Return self<value.
 |  
 |  __ne__(self, value, /)
 |      Return self!=value.
 |  
 |  __new__(*args, **kwargs) from builtins.type
 |      Create and return a new object.  See help(type) for accurate signature.
 |  
 |  __repr__(self, /)
 |      Return repr(self).
 |  
 |  __setitem__(self, key, value, /)
 |      Set self[key] to value.
 |  
 |  __sizeof__(...)
 |      D.__sizeof__() -> size of D in memory, in bytes
 |  
 |  clear(...)
 |      D.clear() -> None.  Remove all items from D.
 |  
 |  copy(...)
 |      D.copy() -> a shallow copy of D
 |  
 |  fromkeys(iterable, value=None, /) from builtins.type
 |      Returns a new dict with keys from iterable and values equal to value.
 |  
 |  get(...)
 |      D.get(k[,d]) -> D[k] if k in D, else d.  d defaults to None.
 |  
 |  items(...)
 |      D.items() -> a set-like object providing a view on D's items
 |  
 |  keys(...)
 |      D.keys() -> a set-like object providing a view on D's keys
 |  
 |  pop(...)
 |      D.pop(k[,d]) -> v, remove specified key and return the corresponding value.
 |      If key is not found, d is returned if given, otherwise KeyError is raised
 |  
 |  popitem(...)
 |      D.popitem() -> (k, v), remove and return some (key, value) pair as a
 |      2-tuple; but raise KeyError if D is empty.
 |  
 |  setdefault(...)
 |      D.setdefault(k[,d]) -> D.get(k,d), also set D[k]=d if k not in D
 |  
 |  update(...)
 |      D.update([E, ]**F) -> None.  Update D from dict/iterable E and F.
 |      If E is present and has a .keys() method, then does:  for k in E: D[k] = E[k]
 |      If E is present and lacks a .keys() method, then does:  for k, v in E: D[k] = v
 |      In either case, this is followed by: for k in F:  D[k] = F[k]
 |  
 |  values(...)
 |      D.values() -> an object providing a view on D's values
 |  
 |  ----------------------------------------------------------------------
 |  Data and other attributes defined here:
 |  
 |  __hash__ = None

Help on class list in module builtins:

class list(object)
 |  list() -> new empty list
 |  list(iterable) -> new list initialized from iterable's items
 |  
 |  Methods defined here:
 |  
 |  __add__(self, value, /)
 |      Return self+value.
 |  
 |  __contains__(self, key, /)
 |      Return key in self.
 |  
 |  __delitem__(self, key, /)
 |      Delete self[key].
 |  
 |  __eq__(self, value, /)
 |      Return self==value.
 |  
 |  __ge__(self, value, /)
 |      Return self>=value.
 |  
 |  __getattribute__(self, name, /)
 |      Return getattr(self, name).
 |  
 |  __getitem__(...)
 |      x.__getitem__(y) <==> x[y]
 |  
 |  __gt__(self, value, /)
 |      Return self>value.
 |  
 |  __iadd__(self, value, /)
 |      Implement self+=value.
 |  
 |  __imul__(self, value, /)
 |      Implement self*=value.
 |  
 |  __init__(self, /, *args, **kwargs)
 |      Initialize self.  See help(type(self)) for accurate signature.
 |  
 |  __iter__(self, /)
 |      Implement iter(self).
 |  
 |  __le__(self, value, /)
 |      Return self<=value.
 |  
 |  __len__(self, /)
 |      Return len(self).
 |  
 |  __lt__(self, value, /)
 |      Return self<value.
 |  
 |  __mul__(self, value, /)
 |      Return self*value.n
 |  
 |  __ne__(self, value, /)
 |      Return self!=value.
 |  
 |  __new__(*args, **kwargs) from builtins.type
 |      Create and return a new object.  See help(type) for accurate signature.
 |  
 |  __repr__(self, /)
 |      Return repr(self).
 |  
 |  __reversed__(...)
 |      L.__reversed__() -- return a reverse iterator over the list
 |  
 |  __rmul__(self, value, /)
 |      Return self*value.
 |  
 |  __setitem__(self, key, value, /)
 |      Set self[key] to value.
 |  
 |  __sizeof__(...)
 |      L.__sizeof__() -- size of L in memory, in bytes
 |  
 |  append(...)
 |      L.append(object) -> None -- append object to end
 |  
 |  clear(...)
 |      L.clear() -> None -- remove all items from L
 |  
 |  copy(...)
 |      L.copy() -> list -- a shallow copy of L
 |  
 |  count(...)
 |      L.count(value) -> integer -- return number of occurrences of value
 |  
 |  extend(...)
 |      L.extend(iterable) -> None -- extend list by appending elements from the iterable
 |  
 |  index(...)
 |      L.index(value, [start, [stop]]) -> integer -- return first index of value.
 |      Raises ValueError if the value is not present.
 |  
 |  insert(...)
 |      L.insert(index, object) -- insert object before index
 |  
 |  pop(...)
 |      L.pop([index]) -> item -- remove and return item at index (default last).
 |      Raises IndexError if list is empty or index is out of range.
 |  
 |  remove(...)
 |      L.remove(value) -> None -- remove first occurrence of value.
 |      Raises ValueError if the value is not present.
 |  
 |  reverse(...)
 |      L.reverse() -- reverse *IN PLACE*
 |  
 |  sort(...)
 |      L.sort(key=None, reverse=False) -> None -- stable sort *IN PLACE*
 |  
 |  ----------------------------------------------------------------------
 |  Data and other attributes defined here:
 |  
 |  __hash__ = None
View Code

2.內置函數補充2

# divmod()
# 應用場景:共有97條數,每頁顯示10條,需多少頁?
r = divmod(97,10)     # 97/10 運算後所得的商和餘數
n1,n2 = divmod(98,10) # 把商和餘數分別賦值給n1,n2
print(r)        # 返回一個元組
print(n1,n2)
輸出結果:
(9, 7)
9 8
###########################################################################################
# isinstance()  判斷一個對象是不是某個類的實例(對象的功能都封裝在類裏,對象是類的實例)
s = "raymond"            # s是字符串
r1 = isinstance(s,str)   # s是str類的實例
r2 = isinstance(s,dict)  # s不是dict類的實例
print(r1,r2)

輸出結果: True False
###########################################################################################
# filter() 是可迭代的對象
# 普通方法:過濾一個列表(保留大於22的元素)
def f1(args):
    result = []
    for item in args:
        if item > 22:
            result.append(item)
    return result
li = [11,22,33,44,55]
ret = f1(li)
print(ret)

輸出結果:
[33, 44, 55]
# -----------------------------------------------------------------
# 用filter()方法過濾大於22的元素
def f2(a):
    if a > 22:
        return True
li = [11,22,33,44,55]
ret = filter(f2,li)
 '''
# 1. filter()內部循環第二個參數,讓每一個循環元素做爲參數傳遞給第一個函數參數,而後執行函數。
# 2. 若是函數返回True,則將元素賦值給ret並保存在列表輸出;函數返回False,則丟棄元素。
 '''
print(list(ret))
#
輸出結果:
[33, 44, 55]
###########################################################################################
# lambda 內部返回bool值
f1 = lambda a: a > 30
a = f1(10)
b = f1(90)
print(a,b)
輸出結果:False True
# -----------------------------------------------------------------
# filter() + lambda 組合使用場景
li = [11,22,33,44,55]
result = filter(lambda a:a>30,li)
print(list(result))
#
輸出結果:
[33, 44, 55]
###########################################################################################
# 通常方法:
li = [11,22,33,44,55]
def f1(args):
    result = []
    for item in args:
        result.append(item+100)
    return result
ret = f1(li)
print(list(ret))

輸出結果:
[111, 122, 133, 144, 155]
# ---------------------------------------------------------------------------
# map()函數,可迭代的對象(能夠for循環的東西)
# 使用map()函數實現以上代碼功能:
li = [11,22,33,44,55]
def f2(a):
    return  a+100
result = map(f2,li)
print(list(result))

輸出結果:
[111, 122, 133, 144, 155]
# ---------------------------------------------------------------------------
# 使用map() + lambda 組合應用場景:對列表中每一個元素進行一樣功能的批量處理
# map() + lambda 實現以上代碼:
li = [11, 22, 33, 44, 55]
result = map(lambda a:a+100,li)
print(list(result))

輸出結果:[111, 122, 133, 144, 155]
---------------------------------------------------------------------------
# 總結:1. filter() 返回True,將列表元素添加到結果中
#       2. map()  將函數返回值添加到結果中
###########################################################################################
#  globals()  表明全部全局變量
#  locals()  表明全部局部變量
NAME = "raymond"
def show():
    a = 123
    b = 456
    print(locals())    # 輸出變量名與值對應的字典
    print(globals())   # 除了輸出全局變量,還有一些python內部的全局變量
show()

輸出結果:
{'b': 456, 'a': 123}
{'__name__': '__main__', '__doc__': '\n1. filter()內部循環第二個參數,讓每一個循環元素做爲參數傳遞給第一個函數參數,而後執行函數。\n2. 若是函數返回True,則將元素賦值給ret並保存在列表輸出;函數返回False,則丟棄元素。\n', '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x000002165F7DCB00>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'E:/PythonProject/python13-day1/text.py', '__cached__': None, 'NAME': 'raymond', 'show': <function show at 0x000002165F382E18>}
###########################################################################################
# hash()
s1 = 'raymond'
s2 = 'jshfjsfhsjdfhsfsfkskdjf'
print("s1:",hash(s1))
print("s2:",hash(s2))
print(len(str(hash(s1))))   # 輸出hash值的長度
輸出結果:隨機輸出兩串19位的數字
s1: 4413186832486012387
s2: -6135389105302975698
###########################################################################################
# max(), min(), sum()
li = [11,22,33,44,55]
r = max(li)
s = min(li)
t = sum (li)
print(r,s,t)
輸出結果:55 11 165
###########################################################################################
pow()
r = pow(2,10)   # 表示2的10次方
print(r)
###########################################################################################
# reverse() 翻轉
li = [11,22,1,1]
li = reversed(li)    # 內部執行了li.reverse()方法,兩個效果同樣
print(li)
###########################################################################################
r = round(1.8)     # 四捨五入
print(r)
輸出結果:2
###########################################################################################
# sorted()
li = [55,11,22,44,33]
li.sort()     # 按列表元素從小到大的順序輸出
sorted(li)    # 按列表元素本來順序輸出
print(li)
###########################################################################################
# zip()
r = ["raymond",11,22,33]
s = ["is",22,33,44]
t = ["boy",33,44,55]

a = zip(r,s)
print(list(a))
# -------------------------------------------------------------------------------------------
b = zip(r,s,t)   # 會把每一個以不一樣列表的元素按相同下標的元素組合成一個元組,每一個元組構成的元素造成新列表。元素少的列表不與別的列表元素匹配。
temp = list(b)[0]      #需調試
ret = ' '.join(temp)
print(ret)

輸出結果:
[('raymond', 'is'), (11, 22), (22, 33), (33, 44)]
raymond is boy
# ###########################################################################################
# 其餘內置函數
id()          # 查看內存地址
issubclass()  # 查看一個類是不是另外一個類的派生類
len()         # 查看長度,2.x按字節計算;3.x按字符計算
memoryview()  # 查看內存地址的一個數
object()      # 表示全部類的父類
range()       # 表示範圍
vars()        # 當前模塊變量哪些可以使用
repr(object)  # 將對象轉化爲供解釋器讀取的形式。
slice()       # 3.x新加的切片功能
View Code

3.上節做業剖析

4.裝飾器概要

# 在a.py文件中建立裝飾器代碼
# 應用場景:能夠對多個業務功能f1(),f2()在不修改的前提下進行添加新的業務功能。
# 能夠根據流水線業務的前後順序在原來功能的前面和後面均可添加新業務功能
def outer(func):
    def inner():
        print('log')
        func()
        print('after')
    return inner

@outer
def f1():
    print("f1")

@outer
def f2():
    print("f2")
# ###########################################################################################
# # 如下代碼在b.py中建立,導入a.py
import a

a.f1()
a.f2()
View Code

5.裝飾器流程剖析儲備知識

def f1():
    print(123)
def f1():
    print(456)
f1()       # 兩個函數f1()相似一個變量名前後賦兩個值,輸出第二個函數的值

輸出結果:456
###########################################################################################
def f1():    # 建立f1()函數,並將整個函數體放入內存中
    print(123)    
def f2(x):   # 此處接收f1函數體,至關於x=f1
    x()      # 此處至關於x()=f1(),是執行f1()函數
f2(f1)       # f1不加括號,表明x形參接收f1所有函數體

輸出結果:123
View Code

6.裝飾器流程剖析之原理步驟、返回值和參數傳遞

  代碼詳解:python

# 如下代碼段在a.py中建立
# 定義好函數未調用時,函數內部不執行
# 函數名(不加括號)代替整個函數;加括號後,執行函數
def outer(func):    # 括號裏func=f1
    def inner():
        print('before')
        func()      # 此處func()=f1(),執行下面原有f1()
        print('after')
    return inner    # 返回值inner表示整個inner函數體,此處會將inner整個函數賦值給f1函數,下面f1()=inner()

@outer
# @outer 功能解釋以下:
# 1. 程序運行到此處,自動執行outer函數,而且將其下面裝飾的函數名f1看成參數傳遞到上面func形參中
# 2. 將outer函數的返回值,從新賦值給f1
# 3. 若是一個函數f1()被裝飾器函數outer()裝飾後,這個函數f1會被從新賦值成裝飾器的內層函數,調用f1()會執行outer函數的內層函數inner()
# 4. 應用場景:假如f1()是一個功能的底層函數,那麼裝飾器函數outer()會在不修改底層函數的前提下,對其進行增長業務功能
def f1():
    print('F1')
# ###########################################################################################
# 如下代碼在b.py中建立,導入a.py
import a

a.f1()

輸出結果:
before
F1
after
View Code

    運行步驟:正則表達式

#單行運行步驟:
def outer(func):     # 第一步
    def inner():     # 第三步
        print('before')  # 第五步
        func()           # 第六步   此處調用下面f1()本來功能
        print('after')   # 第八步
    return inner     # 第四步    此處若是inner+(),則表明執行inner(),返回值爲None;從新賦值給f1,f1()返回None,改變原有f1()功能。

@outer              # @outer+f1()總體: 第二步
def f1():
    print('F1')     # 第七步 (調用原本函數功能)
View Code

  返回值和參數:算法

# 完整裝飾器函數調用,可接收任意參數
def outer(*args,**kwargs):      # 可接收任意個參數
    def inner(*args,**kwargs):
        print('before')
        r = func()
        print('after')
        return r     
    return inner

@outer
def f1(arg):        # 調用f1()傳一個參數
    print('F1')
    return  123     # 原函數f1()帶有返回值的狀況

@outer
def f2(arg1,arg2):  # def f1(arg):        # 調用f2()傳兩個參數,也能夠有更多參數
    print('F2')
    return  456
#------------------------------------------------------------------------------------
# 如下代碼在b.py中建立,導入a.py
import a

a.f1(3)
a.f2(2,3)
View Code

7.實例:用戶管理程序

8.今日做業

第五章.雙層裝飾器、字符串格式化、生成器、迭代器以及重要模塊介紹

1.雙層裝飾器實現用戶登陸和權限驗證1

2.雙層裝飾器實現用戶登陸和權限驗證2

3.多層裝飾器原理

4.python字符串格式化

  Python的字符串格式化有兩種方式: 百分號方式、format方式shell

  百分號的方式相對來講比較老,而format方式則是比較先進的方式,企圖替換古老的方式,目前二者並存。編程

百分號方式:json

%[(name)][flags][width].[precision]typecode
  • (name)      可選,用於選擇指定的key
  • flags          可選,可供選擇的值有:
    • +       右對齊;正數前加正好,負數前加負號;
    • -        左對齊;正數前無符號,負數前加負號;
    • 空格    右對齊;正數前加空格,負數前加負號;
    • 0        右對齊;正數前無符號,負數前加負號;用0填充空白處
  • width         可選,佔有寬度
  • .precision   可選,小數點後保留的位數
  • typecode    必選
    • s,獲取傳入對象的__str__方法的返回值,並將其格式化到指定位置
    • r,獲取傳入對象的__repr__方法的返回值,並將其格式化到指定位置
    • c,整數:將數字轉換成其unicode對應的值,10進制範圍爲 0 <= i <= 1114111(py27則只支持0-255);字符:將字符添加到指定位置
    • o,將整數轉換成 八  進製表示,並將其格式化到指定位置
    • x,將整數轉換成十六進制表示,並將其格式化到指定位置
    • d,將整數、浮點數轉換成 十 進製表示,並將其格式化到指定位置
    • e,將整數、浮點數轉換成科學計數法,並將其格式化到指定位置(小寫e)
    • E,將整數、浮點數轉換成科學計數法,並將其格式化到指定位置(大寫E)
    • f, 將整數、浮點數轉換成浮點數表示,並將其格式化到指定位置(默認保留小數點後6位)
    • F,同上
    • g,自動調整將整數、浮點數轉換成 浮點型或科學計數法表示(超過6位數用科學計數法),並將其格式化到指定位置(若是是科學計數則是e;)
    • G,自動調整將整數、浮點數轉換成 浮點型或科學計數法表示(超過6位數用科學計數法),並將其格式化到指定位置(若是是科學計數則是E;)
    • %,當字符串中存在格式化標誌時,須要用 %%表示一個百分號

注:Python中百分號格式化是不存在自動將整數轉換成二進制表示的方式windows

經常使用格式化:瀏覽器

tpl = "i am %s" % "alex"
 
tpl = "i am %s age %d" % ("alex", 18)
 
tpl = "i am %(name)s age %(age)d" % {"name": "alex", "age": 18}
 
tpl = "percent %.2f" % 99.97623
 
tpl = "i am %(pp).2f" % {"pp": 123.425556, }
 
tpl = "i am %.2f %%" % {"pp": 123.425556, }

Format方式:安全

[[fill]align][sign][#][0][width][,][.precision][type]
  •  fill           【可選】空白處填充的字符
  • align        【可選】對齊方式(需配合width使用)
  • <,內容左對齊
  • >,內容右對齊(默認)
  • =,內容右對齊,將符號放置在填充字符的左側,且只對數字類型有效。 即便:符號+填充物+數字
  • ^,內容居中
  • sign         【可選】有無符號數字
    • +,正號加正,負號加負;
    •  -,正號不變,負號加負;
    • 空格 ,正號空格,負號加負;
  • #            【可選】對於二進制、八進制、十六進制,若是加上#,會顯示 0b/0o/0x,不然不顯示
  • ,            【可選】爲數字添加分隔符,如:1,000,000
  • width       【可選】格式化位所佔寬度
  • .precision 【可選】小數位保留精度
  • type         【可選】格式化類型
    • 傳入」 字符串類型 「的參數
      • s,格式化字符串類型數據
      • 空白,未指定類型,則默認是None,同s
    • 傳入「 整數類型 」的參數
      • b,將10進制整數自動轉換成2進製表示而後格式化
      • c,將10進制整數自動轉換爲其對應的unicode字符
      • d,十進制整數
      • o,將10進制整數自動轉換成8進製表示而後格式化;
      • x,將10進制整數自動轉換成16進製表示而後格式化(小寫x)
      • X,將10進制整數自動轉換成16進製表示而後格式化(大寫X)
    • 傳入「 浮點型或小數類型 」的參數
      • e, 轉換爲科學計數法(小寫e)表示,而後格式化;
      • E, 轉換爲科學計數法(大寫E)表示,而後格式化;
      • f , 轉換爲浮點型(默認小數點後保留6位)表示,而後格式化;
      • F, 轉換爲浮點型(默認小數點後保留6位)表示,而後格式化;
      • g, 自動在e和f中切換
      • G, 自動在E和F中切換
      • %,顯示百分比(默認顯示小數點後6位)

 經常使用格式化:

tpl = "i am {}, age {}, {}".format("seven", 18, 'alex')
  
tpl = "i am {}, age {}, {}".format(*["seven", 18, 'alex'])
  
tpl = "i am {0}, age {1}, really {0}".format("seven", 18)
  
tpl = "i am {0}, age {1}, really {0}".format(*["seven", 18])
  
tpl = "i am {name}, age {age}, really {name}".format(name="seven", age=18)
  
tpl = "i am {name}, age {age}, really {name}".format(**{"name": "seven", "age": 18})
  
tpl = "i am {0[0]}, age {0[1]}, really {0[2]}".format([1, 2, 3], [11, 22, 33])
  
tpl = "i am {:s}, age {:d}, money {:f}".format("seven", 18, 88888.1)
  
tpl = "i am {:s}, age {:d}".format(*["seven", 18])
  
tpl = "i am {name:s}, age {age:d}".format(name="seven", age=18)
  
tpl = "i am {name:s}, age {age:d}".format(**{"name": "seven", "age": 18})
 
tpl = "numbers: {:b},{:o},{:d},{:x},{:X}, {:%}".format(15, 15, 15, 15, 15, 15.87623, 2)
 
tpl = "numbers: {:b},{:o},{:d},{:x},{:X}, {:%}".format(15, 15, 15, 15, 15, 15.87623, 2)
 
tpl = "numbers: {0:b},{0:o},{0:d},{0:x},{0:X}, {0:%}".format(15)
 
tpl = "numbers: {num:b},{num:o},{num:d},{num:x},{num:X}, {num:%}".format(num=15)

6.python生成器

一個函數調用時返回一個迭代器,那這個函數就叫作生成器(generator);若是函數中包含yield語法,那這個函數就會變成生成器;

def func():
    yield 1
    yield 2
    yield 3
    yield 4

上述代碼中:func是函數稱爲生成器,當執行此函數func()時會獲得一個迭代器。

>>> temp = func()
>>> temp.__next__()
1
>>> temp.__next__()
2
>>> temp.__next__()
3
>>> temp.__next__()
4
>>> temp.__next__()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration

 示例: 

# 生成器(具備生成數據的功能叫生成器)
def func():     # 若是函數裏有yield,則該函數變爲生成器
    print('start')
    yield 1
    yield 2
    yield 3
ret = func()    # 函數執行到此處,並不執行函數
print(ret)      # 返回一個生成器對象(generator object),循環這個對象才能夠取值
輸出結果:
<generator object func at 0x0000028098630FC0>
----------------------------------------------------------------------------------------
r = ret.__next__()      # 調用此函數找到yield,每次只能取一個yield後面的值
print(r)
輸出結果:
<generator object func at 0x0000024DA6F90FC0>
start
1

r = ret.__next__()      # 合併上次取到的值,再取第二個yield後面的值。
print(r)
輸出結果:
<generator object func at 0x0000024DA6F90FC0>
start
1
2
###########################################################################################
# 用for循環取生成器中的值,結果輸出所有生成器的返回值
def func():
    print('start')
    yield 1
    yield 2
    yield 3
ret = func()

for item in ret:        # 每循環一次,去func()中依次取函數輸出值以及yield後面的返回值。
    print(item)         # 分別取到:start,1,2,3

輸出結果:
start
1
2
3
View Code

7.基於生成器實現range功能以及python迭代器

# 基於生成器實現range功能
def myrange(arg):
    start = 0
    while True:
        if start > arg:
            return
        else:
            yield start  # 具備生成數據功能的叫生成器。
            start += 1
ret = myrange(5)    # 可迭代的對對象,叫迭代器。可經過__next__()去取值,一直到取完值後,報錯!
r = ret.__next__()
print(r)            # 輸出結果:0
r = ret.__next__()
print(r)            # 輸出結果:0,1
View Code

8.python函數遞歸

# 若是函數無返回值,默認返回None
def fun(n):     # 遞歸函數
    n = n + 1
    if n >= 4:
        return  'end'
    return fun(n)
r = fun(1)
print(r)
輸出結果:end
View Code

9.利用遞歸實現階乘實例

# 遞歸函數(函數反覆調用本身)
def func(num):
    if num ==1:
        return 1
    return num*func(num - 1)
x = func(7)
print(x)

輸出結果:5040

10.python模塊介紹

  在python安裝目錄中:D:\Program Files\Python\Python36\Lib

  此目錄中包含全部python模塊,如:xxx.py

  模塊分爲:

  • 內置模塊
  • 自定義模塊
  • 第三方模塊

  模塊先導入,後使用。示例以下:

import sys
print(sys.path)

輸出結果:
['E:\\PythonProject\\python13-day1', 'E:\\PythonProject\\python13-day1', 'E:\\PythonProject\\zgf', 'E:\\PythonProject\\python13-day1\\venv\\Scripts\\python36.zip', 'E:\\PythonProject\\python13-day1\\venv\\DLLs', 'E:\\PythonProject\\python13-day1\\venv\\lib', 'E:\\PythonProject\\python13-day1\\venv\\Scripts', 'D:\\Program Files\\Python\\Python36\\Lib', 'D:\\Program Files\\Python\\Python36\\DLLs', 'E:\\PythonProject\\python13-day1\\venv', 'E:\\PythonProject\\python13-day1\\venv\\lib\\site-packages', 'D:\\Program Files\\JetBrains\\PyCharm professional 2017.3.2\\helpers\\pycharm_matplotlib_backend']

  單模塊用法:

  • import  模塊名
  • from 模塊名 import 函數名

  嵌套在文件夾裏的模塊:

  • from 文件夾名 import  文件名
  • from 文件夾名 import  文件名 as 別名

注:自定義模塊名不要與內置模塊名重名

11.安裝第三方模塊

  pip3 install requests  (python 3.x 自帶pip3安裝工具,2.x不帶,需本身安裝)

  源碼安裝:解壓requests包-->進入目錄-->python3 setup.py install

12.python序列化之json和pickle模塊

# python序列化和反序列化:dumps(),loads()
import json

li = ['k1','v1']
ret = json.dumps(li)  # 將python基本數據類型轉化爲字符串格式
print(ret,type(ret))

輸出結果:
["k1", "v1"] <class 'str'>
##########################################################################################
# s1 = '{'k1':123}'
import json
li = '["alex","eric"] '
ret = json.loads(li)   # 將字符串格式轉化成python基本數據類型,反序列化時列表內必定要使用""
print(ret,type(ret))

輸出結果:
['alex', 'eric'] <class 'list'>
###########################################################################################
# # 基於天氣API獲取天氣相關JSON數據
import requests
import json
response = requests.get('http://wthrcdn.etouch.cn/weather_mini?city=%E5%8C%97%E4%BA%AC')
response.encoding = 'utf-8'
print(response.text)       # 獲取 http請求返回的數據

輸出結果:
{"data":{"yesterday":{"date":"25日星期三","high":"高溫 25℃","fx":"南風","low":"低溫 11℃","fl":"<![CDATA[3-4級]]>","type":"多雲"},"city":"北京","aqi":"101","forecast":[{"date":"26日星期四","high":"高溫 26℃","fengli":"<![CDATA[<3級]]>","low":"低溫 11℃","fengxiang":"南風","type":""},{"date":"27日星期五","high":"高溫 25℃","fengli":"<![CDATA[3-4級]]>","low":"低溫 13℃","fengxiang":"西南風","type":""},{"date":"28日星期六","high":"高溫 27℃","fengli":"<![CDATA[3-4級]]>","low":"低溫 17℃","fengxiang":"西南風","type":""},{"date":"29日星期天","high":"高溫 29℃","fengli":"<![CDATA[<3級]]>","low":"低溫 17℃","fengxiang":"南風","type":"多雲"},{"date":"30日星期一","high":"高溫 26℃","fengli":"<![CDATA[3-4級]]>","low":"低溫 15℃","fengxiang":"東北風","type":"多雲"}],"ganmao":"各項氣象條件適宜,無明顯降溫過程,發生感冒機率較低。","wendu":"24"},"status":1000,"desc":"OK"}

ret = json.loads(response.text)    # 將http返回的字符串轉化爲python基本數據類型字典
print(ret)

 輸出結果:
{"data":{"yesterday":{"date":"25日星期三","high":"高溫 25℃","fx":"南風","low":"低溫 11℃","fl":"<![CDATA[3-4級]]>","type":"多雲"},"city":"北京","aqi":"101","forecast":[{"date":"26日星期四","high":"高溫 26℃","fengli":"<![CDATA[<3級]]>","low":"低溫 11℃","fengxiang":"南風","type":""},{"date":"27日星期五","high":"高溫 25℃","fengli":"<![CDATA[3-4級]]>","low":"低溫 13℃","fengxiang":"西南風","type":""},{"date":"28日星期六","high":"高溫 27℃","fengli":"<![CDATA[3-4級]]>","low":"低溫 17℃","fengxiang":"西南風","type":""},{"date":"29日星期天","high":"高溫 29℃","fengli":"<![CDATA[<3級]]>","low":"低溫 17℃","fengxiang":"南風","type":"多雲"},{"date":"30日星期一","high":"高溫 26℃","fengli":"<![CDATA[3-4級]]>","low":"低溫 15℃","fengxiang":"東北風","type":"多雲"}],"ganmao":"各項氣象條件適宜,無明顯降溫過程,發生感冒機率較低。","wendu":"24"},"status":1000,"desc":"OK"}
{'data': {'yesterday': {'date': '25日星期三', 'high': '高溫 25℃', 'fx': '南風', 'low': '低溫 11℃', 'fl': '<![CDATA[3-4級]]>', 'type': '多雲'}, 'city': '北京', 'aqi': '101', 'forecast': [{'date': '26日星期四', 'high': '高溫 26℃', 'fengli': '<![CDATA[<3級]]>', 'low': '低溫 11℃', 'fengxiang': '南風', 'type': ''}, {'date': '27日星期五', 'high': '高溫 25℃', 'fengli': '<![CDATA[3-4級]]>', 'low': '低溫 13℃', 'fengxiang': '西南風', 'type': ''}, {'date': '28日星期六', 'high': '高溫 27℃', 'fengli': '<![CDATA[3-4級]]>', 'low': '低溫 17℃', 'fengxiang': '西南風', 'type': ''}, {'date': '29日星期天', 'high': '高溫 29℃', 'fengli': '<![CDATA[<3級]]>', 'low': '低溫 17℃', 'fengxiang': '南風', 'type': '多雲'}, {'date': '30日星期一', 'high': '高溫 26℃', 'fengli': '<![CDATA[3-4級]]>', 'low': '低溫 15℃', 'fengxiang': '東北風', 'type': '多雲'}], 'ganmao': '各項氣象條件適宜,無明顯降溫過程,發生感冒機率較低。', 'wendu': '24'}, 'status': 1000, 'desc': 'OK'}
###########################################################################################
# 將文件內容序列化和反序列化:dump(),load()
import json
li =[11,22,33]
json.dump(li,open('db1','w'))     # 把li列表轉爲字符串,再寫入db文件中

ret = json.load(open('db1','r'))  # 先讀db文件,而後再把文件中字符串數據反序列化爲列表
print(ret,type(ret))

輸出結果:
[11, 22, 33] <class 'list'>
###########################################################################################
# python 序列化之pickle,只提供python使用
import pickle
li = [11,22,33]
r = pickle.dumps(li)    # 序列化爲python特定的格式
print(r)

輸出結果:
b'\x80\x03]q\x00(K\x0bK\x16K!e.'
---------------------------------------------------------------------------------
ret = pickle.loads(r)   # 把特定的格式反序列化爲原來的列表
print(ret)

輸出結果:
[11, 22, 33]
###########################################################################################
import  pickle
li = [11,22,33,44]
pickle.dump(li,open('db2','wb'))  # pickle序列化列表數據類型到文件,必須以字節碼寫入
# 寫入文件內容是python特定格式:�]q (KKK!K,e.
r = pickle.load(open('db2','rb'))  # 把文件亂碼內容還原爲列表數據
print(r)

輸出結果:
[11, 22, 33, 44]
View Code

 總結:

  • json:只能處理python的基本數據類型(dict,lixt,tuple,str,int,float,True,False);支持各類編程語言數據的序列化,適合基本數據類型。

  • pickle:除了能夠處理json的基本數據類型外,還能夠用於複雜數據類型的操做。例如:可記憶存儲遊戲闖關類數據文檔。但只支持python使用,python不一樣版本之間的序列化和反序列化,可能報錯。

13.基於天氣API獲取天氣相關JSON數據

# 基於天氣API獲取天氣相關JSON數據
import requests
import json
response = requests.get('http://wthrcdn.etouch.cn/weather_mini?city=%E5%8C%97%E4%BA%AC')
response.encoding = 'utf-8'
print(response.text)       # 獲取 http請求返回的數據

輸出結果:
{"data":{"yesterday":{"date":"25日星期三","high":"高溫 25℃","fx":"南風","low":"低溫 11℃","fl":"<![CDATA[3-4級]]>","type":"多雲"},"city":"北京","aqi":"101","forecast":[{"date":"26日星期四","high":"高溫 26℃","fengli":"<![CDATA[<3級]]>","low":"低溫 11℃","fengxiang":"南風","type":""},{"date":"27日星期五","high":"高溫 25℃","fengli":"<![CDATA[3-4級]]>","low":"低溫 13℃","fengxiang":"西南風","type":""},{"date":"28日星期六","high":"高溫 27℃","fengli":"<![CDATA[3-4級]]>","low":"低溫 17℃","fengxiang":"西南風","type":""},{"date":"29日星期天","high":"高溫 29℃","fengli":"<![CDATA[<3級]]>","low":"低溫 17℃","fengxiang":"南風","type":"多雲"},{"date":"30日星期一","high":"高溫 26℃","fengli":"<![CDATA[3-4級]]>","low":"低溫 15℃","fengxiang":"東北風","type":"多雲"}],"ganmao":"各項氣象條件適宜,無明顯降溫過程,發生感冒機率較低。","wendu":"24"},"status":1000,"desc":"OK"}

ret = json.loads(response.text)    # 將http返回的字符串轉化爲python基本數據類型字典
print(ret)

 輸出結果:
{"data":{"yesterday":{"date":"25日星期三","high":"高溫 25℃","fx":"南風","low":"低溫 11℃","fl":"<![CDATA[3-4級]]>","type":"多雲"},"city":"北京","aqi":"101","forecast":[{"date":"26日星期四","high":"高溫 26℃","fengli":"<![CDATA[<3級]]>","low":"低溫 11℃","fengxiang":"南風","type":""},{"date":"27日星期五","high":"高溫 25℃","fengli":"<![CDATA[3-4級]]>","low":"低溫 13℃","fengxiang":"西南風","type":""},{"date":"28日星期六","high":"高溫 27℃","fengli":"<![CDATA[3-4級]]>","low":"低溫 17℃","fengxiang":"西南風","type":""},{"date":"29日星期天","high":"高溫 29℃","fengli":"<![CDATA[<3級]]>","low":"低溫 17℃","fengxiang":"南風","type":"多雲"},{"date":"30日星期一","high":"高溫 26℃","fengli":"<![CDATA[3-4級]]>","low":"低溫 15℃","fengxiang":"東北風","type":"多雲"}],"ganmao":"各項氣象條件適宜,無明顯降溫過程,發生感冒機率較低。","wendu":"24"},"status":1000,"desc":"OK"}
{'data': {'yesterday': {'date': '25日星期三', 'high': '高溫 25℃', 'fx': '南風', 'low': '低溫 11℃', 'fl': '<![CDATA[3-4級]]>', 'type': '多雲'}, 'city': '北京', 'aqi': '101', 'forecast': [{'date': '26日星期四', 'high': '高溫 26℃', 'fengli': '<![CDATA[<3級]]>', 'low': '低溫 11℃', 'fengxiang': '南風', 'type': ''}, {'date': '27日星期五', 'high': '高溫 25℃', 'fengli': '<![CDATA[3-4級]]>', 'low': '低溫 13℃', 'fengxiang': '西南風', 'type': ''}, {'date': '28日星期六', 'high': '高溫 27℃', 'fengli': '<![CDATA[3-4級]]>', 'low': '低溫 17℃', 'fengxiang': '西南風', 'type': ''}, {'date': '29日星期天', 'high': '高溫 29℃', 'fengli': '<![CDATA[<3級]]>', 'low': '低溫 17℃', 'fengxiang': '南風', 'type': '多雲'}, {'date': '30日星期一', 'high': '高溫 26℃', 'fengli': '<![CDATA[3-4級]]>', 'low': '低溫 15℃', 'fengxiang': '東北風', 'type': '多雲'}], 'ganmao': '各項氣象條件適宜,無明顯降溫過程,發生感冒機率較低。', 'wendu': '24'}, 'status': 1000, 'desc': 'OK'}
View Code

14.python時間處理之time&datetime模塊 

import time
import datetime

print(time.time())      #1 時間戳 (UNIX官方發佈時間1970-01-01 00:00:00 距離當前時間段的秒數)  *****
print(time.ctime())     #2 打印當前時間
print(time.ctime(3600)) #3 把時間戳轉爲具體日期
print(time.mktime(time.localtime()))    #4 把當前時間轉爲距1970年的時間戳
print(time.sleep(3))  #5 CPU中止工做3秒   *****
print(time.clock())     #6 計算CPU執行時間
print(time.gmtime())    #7 結構化時間(元組格式),以世界UTC標準時間爲標準輸出,北京與UTC時間相差8小時。UTC=1000,北京=1800
print(time.localtime()) #8 輸出本地當地當前時間,與本地PC時間相同  *****
print(time.strftime('%Y-%m-%d %H:%M:%S'))   #9 字符串格式化輸出時間    *****
print(time.strptime('2018-04-27 10:43:39','%Y-%m-%d %H:%M:%S'))  #10 把字符串格式化時間轉爲結構化時間 *****
a = time.strptime('2018-04-27 10:43:39','%Y-%m-%d %H:%M:%S')
print(a.tm_year)    #11 可單獨取出日期和時間的年、月、日 和 時,分,秒
print(a.tm_mon)     #12 只輸出月份
print(a.tm_mday)    #13 只輸出幾號
print(a.tm_wday)    #14 當前日期是本週中的第幾天 (週一:0)
print(a.tm_yday)    #15 當前日期是本年中的第幾天

print(datetime.datetime.now())  #16 輸出當前系統的規範格式時間


輸出結果依次爲如下16行:
1524799294.4669478
Fri Apr 27 11:21:34 2018
Thu Jan  1 09:00:00 1970
1524799294.0
None
7.2934459635882e-07
time.struct_time(tm_year=2018, tm_mon=4, tm_mday=27, tm_hour=3, tm_min=21, tm_sec=37, tm_wday=4, tm_yday=117, tm_isdst=0)
time.struct_time(tm_year=2018, tm_mon=4, tm_mday=27, tm_hour=11, tm_min=21, tm_sec=37, tm_wday=4, tm_yday=117, tm_isdst=0)
2018-04-27 11:21:37
time.struct_time(tm_year=2018, tm_mon=4, tm_mday=27, tm_hour=10, tm_min=43, tm_sec=39, tm_wday=4, tm_yday=117, tm_isdst=-1)
2018
4
27
4
117
2018-04-27 11:21:37.479549
# ###########################################################################################
# python中時間日期格式化符號:

# %y 兩位數的年份表示(00-99)
# %Y 四位數的年份表示(000-9999)
# %m 月份(01-12)
# %d 月內中的一天(0-31)
# %H 24小時制小時數(0-23)
# %I 12小時制小時數(01-12)
# %M 分鐘數(00=59)
# %S 秒(00-59)
# %a 本地簡化星期名稱
# %A 本地完整星期名稱
# %b 本地簡化的月份名稱
# %B 本地完整的月份名稱
# %c 本地相應的日期表示和時間表示
# %j 年內的一天(001-366)
# %p 本地A.M.或P.M.的等價符
# %U 一年中的星期數(00-53)星期天爲星期的開始
# %w 星期(0-6),星期天爲星期的開始
# %W 一年中的星期數(00-53)星期一爲星期的開始
# %x 本地相應的日期表示
# %X 本地相應的時間表示
# %Z 當前時區的名稱
# %% %號自己
View Code

15.python日誌處理之logging模塊

用於便捷記錄日誌且線程安全的模塊

import logging
 
 
logging.basicConfig(filename='log.log',
                    format='%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s',
                    datefmt='%Y-%m-%d %H:%M:%S %p',
                    level=10)
 
logging.debug('debug')
logging.info('info')
logging.warning('warning')
logging.error('error')
logging.critical('critical')
logging.log(10,'log')

對於level級別以下所示:

CRITICAL = 50
FATAL = CRITICAL
ERROR = 40
WARNING = 30
WARN = WARNING
INFO = 20
DEBUG = 10
NOTSET = 0

注:只有大於當前日誌等級的操做纔會被記錄。

對於格式,有以下屬性能夠配置:

16.今日做業以及代碼目錄

第六章.python反射、重要模塊以及正則表達式

1.ATM做業分析

2.python反射模塊之getattr,hasattr,setattr,delattr

# python之反射概念:利用字符串的形式去對象(模塊)中操做(查找/檢查/刪除/設置)成員(函數)
# 下面反射函數中m表明模塊名,f表明與函數同名的字符串
# getattr(m,f):  用字符串f查找模塊m ;
# hasattr(m,f):  判斷字符串f是否再模塊m中,函數返回True或False ;
# setattr(m,f,v) 給對象的屬性賦值,若是此屬性不存在,會先建立,而後再賦值 ;
# delattr(m,f):  delattr 函數用於刪除屬性。至關於del m.f() ; 若是屬性不存在,會報錯
###########################################################################################
# 建立文件名爲commons.py,代碼以下:
def login():
    print('login')
def logout():
    print('logout')
def home():
    print('home')
# -------------------------------------------------------------------------------------------
# 建立index.py文件
# import commons
# # 導入模塊時,會先放在內存中;反射函數基於內存操做模塊,從新reload模塊,即可回覆成員
#
def run():
    inp = input('請輸入訪問地址:')     # inp 表示輸入的是字符串
    if hasattr(commons,inp):   # bool型,爲真,執行下面函數
        func = getattr(commons,inp)   # 此處inp能夠加入單個字符串形式的成員名,如:'login'
        func()              # 若是找到模塊中的成員,則執行該成員函數
    else:
        print('404')


if __name__ == '__main__':
    run()
###########################################################################################
# 經過字符串查找任意模塊及函數
# obj = __import__('commons')  # 表示導入commons模塊,等價於 import commons
# obj.login()       # 導入後執行commons模塊中的login()
import commons
def run():
    inp = input('請輸入訪問地址:')
    m,f = inp.split('/')    # 把輸入的字符串用 m/f 形式分割爲:模塊名/函數名
    obj = __import__(m)     # m表示輸入的字符串形式的模塊名,若是導入一個庫中全部模塊,此處修改成(解釋見下段代碼):obj = __import__("lib."+m,fromlist=True)
    if hasattr(obj,f):
        func = getattr(obj,f)
        func()
    else:
        print('404')

if __name__ == '__main__':
    run()
###########################################################################################
# 假設全部模塊在lib文件夾庫中,需修改導入方式以下:
# 如下方法最經常使用,用一個主文件index導入一個庫(文件夾裏存儲着不少模塊文件)中的全部模塊文件
obj = __import__("lib."+m,fromlist=True)
View Code

3.python模塊中特殊變量

# 特殊全局變量:__file__, __doc__, __cached__, (__name__, __package__)最後兩個必須掌握
print(vars(test1))       # 打印test1模塊中的變量
print(test1.__dict__)    # 同上

print(__doc__)      # 獲取當前文件中'''註釋部分'''的文檔,#號後的註釋不獲取
print(__cached__)   # python導入一個模塊時,會生成一個*.pyc文件(字節碼),__cached__指定pyc文件的路徑
print(__file__)     # 打印當前py文件所在路徑;若是跳到py所在目錄下執行文件,只能取到py文件名
# -----------------------------------------------------------------------------------------
# print(__package__)  輸出文件所在的包名
# 假設:s1導入s2,s2在bin目錄下,那麼在s1中代碼以下:
from bin import s2
print(s2.__packge__)
輸出結果:bin
# -----------------------------------------------------------------------------------------
# __name__ == __main__,只有執行當前文件時候,當前文件的特殊變量__name__=__main__
def fun():
    print('run')
if __name__ == "__main__":  # 此時 __name__ == "__main__"爲真,因此執行下面函數;若是被另外文件調用fun(),則__name__ != "__main__",爲假,不執行下面函數fun()
    fun()
###########################################################################################
import os
import sys
print(os.path.abspath(__file__))   # 永遠取到的是文件的絕對路徑,包含文件名
print(os.path.dirname(__file__))   # 返回原文件的上一級目錄
ret = print(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))   # 返回原文件路徑的上兩級目錄
sys.path.append(ret)    # 若是原文件上兩級的目錄添加到sys.path路徑中,這樣py文件所在的上兩級目錄放在任何地方均可以執行
View Code

4.python之sys模塊

用於提供對解釋器相關的操做

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

5.python之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    輸出操做系統特定的路徑分隔符,win下爲"\\",Linux下爲"/"
os.linesep    輸出當前平臺使用的行終止符,win下爲"\t\n",Linux下爲"\n"
os.pathsep    輸出用於分割文件路徑的字符串
os.name    輸出字符串指示當前使用平臺。win->'nt'; Linux->'posix'
os.system("bash command")  運行shell命令,直接顯示
os.environ  獲取系統環境變量
os.path.abspath(path)  返回path規範化的絕對路徑
os.path.split(path)  將path分割成目錄和文件名二元組返回
os.path.dirname(path)  返回path的目錄。其實就是os.path.split(path)的第一個元素
os.path.basename(path)  返回path最後的文件名。如何path以/或\結尾,那麼就會返回空值。即os.path.split(path)的第二個元素
os.path.exists(path)  若是path存在,返回True;若是path不存在,返回False
os.path.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所指向的文件或者目錄的最後修改時間
View Code
  • os模塊中幾個重要的操做函數
import os
import sys
print(os.path.abspath(__file__))   # 永遠取到的是文件的絕對路徑,包含文件名
print(os.path.dirname(__file__))   # 返回原文件的上一級目錄
ret = print(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))   # 返回原文件路徑的上兩級目錄
sys.path.append(ret)    # 若是原文件上兩級的目錄添加到sys.path路徑中,這樣py文件所在的上兩級目錄放在任何地方均可以執行
###########################################################################################
import os

os.path.abspath(path='')        # 返回path規範化的絕對路徑
os.path.dirname(path='')        # 返回path的目錄。其實就是os.path.split(path)的第一個元素
os.path.join(path1[, path2[, ...]])   # 將多個路徑組合後返回,第一個絕對路徑以前的參數將被忽略

6.python之hashlib加密模塊

用於加密相關的操做,代替了md5模塊和sha模塊,主要提供 SHA1, SHA224, SHA256, SHA384, SHA512 ,MD5 算法

import md5
hash = md5.new()
hash.update('admin')
print hash.hexdigest()
MD5—廢棄
import sha

hash = sha.new()
hash.update('admin')
print hash.hexdigest()
SHA—廢棄

hashlib用法:

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()

以上加密算法雖然依然很是厲害,但時候存在缺陷,即:經過撞庫能夠反解。因此,有必要對加密算法中添加自定義key再來作加密。 

import hashlib
 
# ######## md5 ########
 
hash = hashlib.md5('898oaFs09f')
hash.update('admin')
print hash.hexdigest()

還不夠吊?python 還有一個 hmac 模塊,它內部對咱們建立 key 和 內容 再進行處理而後再加密  

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

到這兒就頂天牛逼了!!!

應用示例:

# hashlib    各類加密對象都保存在hashlib模塊中,必須先導入,再使用
# MD5        不可逆,只能加密,不能解密
import hashlib
obj = hashlib.md5(bytes('abcdef',encoding='utf-8'))  # 對123加密後的值,用abcdef進行再次加密
# obj = obj.update('123')     # 適用與於Python 2.X
obj.update(bytes('123',encoding='utf-8'))    # 適用與於Python 3.X
result = obj.hexdigest()   # 獲取加密後的值
print(result)
View Code

7.configparser模塊

 configparser用於處理特定格式的文件,其本質上是利用open來操做文件。

# 建立特定格式文件xxxooo.txt

[section1]    # 節點
  k1 = 123      # 鍵值對
  k2 = raymond
  k3:v3         # 鍵值對 


[section2]    # 節點
  k1 = 456      # 鍵值對


[section3]
     |
     |
[sectionx]    # 第x個節點塊
View Code
  • 獲取全部節點
import configparser
 
config = configparser.ConfigParser()
config.read('xxxooo', encoding='utf-8')
ret = config.sections()
print(ret)
  • 獲取指定節點下全部的鍵值對
import configparser
 
config = configparser.ConfigParser()
config.read('xxxooo', encoding='utf-8')
ret = config.items('section1')
print(ret)
  • 獲取指定節點下全部的鍵
import configparser
 
config = configparser.ConfigParser()
config.read('xxxooo', encoding='utf-8')
ret = config.options('section1')
print(ret)
  • 獲取指定節點下指定key的值
import configparser
 
config = configparser.ConfigParser()
config.read('xxxooo', encoding='utf-8')
 
 
v = config.get('section1', 'k1')
# v = config.getint('section1', 'k1')
# v = config.getfloat('section1', 'k1')
# v = config.getboolean('section1', 'k1')
 
print(v)
  • 檢查、刪除、添加節點
import configparser
 
config = configparser.ConfigParser()
config.read('xxxooo', encoding='utf-8')
 
 
# 檢查
has_sec = config.has_section('section1')
print(has_sec)
 
# 添加節點
config.add_section("SEC_1")
config.write(open('xxxooo', 'w'))
 
# 刪除節點
config.remove_section("SEC_1")
config.write(open('xxxooo', 'w'))
  • 檢查、刪除、設置指定組內的鍵值對
import configparser
 
config = configparser.ConfigParser()
config.read('xxxooo', encoding='utf-8')
 
# 檢查
has_opt = config.has_option('section1', 'k1')
print(has_opt)
 
# 刪除
config.remove_option('section1', 'k1')
config.write(open('xxxooo', 'w'))
 
# 設置
config.set('section1', 'k10', "123")
config.write(open('xxxooo', 'w'))

8.shutil模塊以及壓縮包處理 

高級的 文件、文件夾、壓縮包 處理模塊 

  • shutil.copyfileobj(fsrc, fdst[, length])

  將文件內容拷貝到另外一個文件中 

import shutil
 
shutil.copyfileobj(open('old.xml','r'), open('new.xml', 'w'))
  • shutil.copyfile(src, dst)

  拷貝文件 

shutil.copyfile('f1.log', 'f2.log')
  • shutil.copymode(src, dst)

  僅拷貝權限。內容、組、用戶均不變

shutil.copymode('f1.log', 'f2.log')
  • shutil.copystat(src, dst)

  僅拷貝狀態的信息,包括:mode bits, atime, mtime, flags

shutil.copystat('f1.log', 'f2.log')
  • shutil.copy(src, dst)

  拷貝文件和權限 

import shutil
 
shutil.copy('f1.log', 'f2.log')
  • shutil.copy2(src, dst)

  拷貝文件和狀態信息 

import shutil
 
shutil.copy2('f1.log', 'f2.log')
  • shutil.ignore_patterns(*patterns)
  • shutil.copytree(src, dst, symlinks=False, ignore=None)

  遞歸的去拷貝文件夾 

import shutil
 
shutil.copytree('folder1', 'folder2', ignore=shutil.ignore_patterns('*.pyc', 'tmp*'))
import shutil

shutil.copytree('f1', 'f2', symlinks=True, ignore=shutil.ignore_patterns('*.pyc', 'tmp*'))
  • shutil.rmtree(path[, ignore_errors[, onerror]])

  遞歸的去刪除文件 

import shutil
 
shutil.rmtree('folder1')
  • shutil.move(src, dst)

  遞歸的去移動文件,它相似mv命令,其實就是重命名。 

import shutil
 
shutil.move('folder1', 'folder3')
  • shutil.make_archive(base_name, format,...)

  建立壓縮包並返回文件路徑,例如:zip、tar

  建立壓縮包並返回文件路徑,例如:zip、tar

    • base_name: 壓縮包的文件名,也能夠是壓縮包的路徑。只是文件名時,則保存至當前目錄,不然保存至指定路徑,
      如:www                        =>保存至當前路徑
      如:/Users/wupeiqi/www =>保存至/Users/wupeiqi/
    • format: 壓縮包種類,「zip」, 「tar」, 「bztar」,「gztar」
    • root_dir: 要壓縮的文件夾路徑(默認當前目錄)
    • owner: 用戶,默認當前用戶
    • group: 組,默認當前組
    • logger: 用於記錄日誌,一般是logging.Logger對象 
#將 /Users/wupeiqi/Downloads/test 下的文件打包放置當前程序目錄
import shutil
ret = shutil.make_archive("wwwwwwwwww", 'gztar', root_dir='/Users/wupeiqi/Downloads/test')
  
  
#將 /Users/wupeiqi/Downloads/test 下的文件打包放置 /Users/wupeiqi/目錄
import shutil
ret = shutil.make_archive("/Users/wupeiqi/wwwwwwwwww", 'gztar', root_dir='/Users/wupeiqi/Downloads/test')

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解壓縮
import tarfile

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

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

tarfile解壓縮
tarfile解壓縮

9.subprocess模塊 

能夠執行shell命令的相關模塊和函數有: 

  • os.system
  • os.spawn*
  • os.popen*          --廢棄
  • popen2.*           --廢棄
  • commands.*      --廢棄,3.x中被移除
import commands

result = commands.getoutput('cmd')
result = commands.getstatus('cmd')
result = commands.getstatusoutput('cmd')
View Code

 以上執行shell命令的相關的模塊和函數的功能均在 subprocess 模塊中實現,並提供了更豐富的功能。

call 

執行命令,返回狀態碼

ret = subprocess.call(["ls", "-l"], shell=False)    # 只獲取狀態碼,不獲取命令執行結果
ret = subprocess.call("ls -l", shell=True)

check_call

執行命令,若是執行狀態碼是 0 ,則返回0,不然拋異常

subprocess.check_call(["ls", "-l"])    

subprocess.check_call("exit 1", shell=True)

check_output

執行命令,若是狀態碼是 0 ,則返回命令執行結果,不然拋異常 

subprocess.check_output(["echo", "Hello World!"])
subprocess.check_output("exit 1", shell=True)

subprocess.check_output("ls -l",shell=True)  # 獲取命令執行結果

subprocess.Popen(...)

用於執行復雜的系統命令

參數:

    • args:shell命令,能夠是字符串或者序列類型(如:list,元組)
    • bufsize:指定緩衝。0 無緩衝,1 行緩衝,其餘 緩衝區大小,負值 系統緩衝
    • stdin, stdout, stderr:分別表示程序的標準輸入、輸出、錯誤句柄
    • preexec_fn:只在Unix平臺下有效,用於指定一個可執行對象(callable object),它將在子進程運行以前被調用
    • close_sfs:在windows平臺下,若是close_fds被設置爲True,則新建立的子進程將不會繼承父進程的輸入、輸出、錯誤管道。
      因此不能將close_fds設置爲True同時重定向子進程的標準輸入、輸出與錯誤(stdin, stdout, stderr)。
    • shell:同上
    • cwd:用於設置子進程的當前目錄
    • env:用於指定子進程的環境變量。若是env = None,子進程的環境變量將從父進程中繼承。
    • universal_newlines:不一樣系統的換行符不一樣,True -> 贊成使用 \n
    • startupinfo與createionflags只在windows下有效
      將被傳遞給底層的CreateProcess()函數,用於設置子進程的一些屬性,如:主窗口的外觀,進程的優先級等等 
import subprocess
ret1 = subprocess.Popen(["mkdir","t1"])
ret2 = subprocess.Popen("mkdir t2", shell=True)
執行普通命令

終端輸入的命令分爲兩種:

  • 輸入便可獲得輸出,如:ifconfig
  • 輸入進行某環境,依賴再輸入,如:python 
import subprocess
# 跳轉到cwd目錄下,執行mkdir命令
obj = subprocess.Popen("mkdir t3", shell=True, cwd='/home/dev',)   
View Code
import subprocess
#經過管道進行輸入內容(stdin),輸出內容(stdout)和捕捉錯誤內容(atderr)
obj = subprocess.Popen(["python"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)  
obj.stdin.write('print 1 \n ')     # 輸入4行內容
obj.stdin.write('print 2 \n ')
obj.stdin.write('print 3 \n ')
obj.stdin.write('print 4 \n ')
obj.stdin.close()

cmd_out = obj.stdout.read()    # 輸出內容
obj.stdout.close()
cmd_error = obj.stderr.read()   # 捕捉錯誤內容
obj.stderr.close()

print cmd_out
print cmd_error
View Code
import subprocess

obj = subprocess.Popen(["python"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
obj.stdin.write('print 1 \n ')
obj.stdin.write('print 2 \n ')
obj.stdin.write('print 3 \n ')
obj.stdin.write('print 4 \n ')

#如下語句同時捕捉輸出管道和錯誤管道的內容,返回一個列表類型,存放輸出和錯誤內容
out_error_list = obj.communicate() 
print out_error_list
View Code
import subprocess

obj = subprocess.Popen(["python"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)


# 把字符串內容放入python解釋器解釋成python可執行代碼
out_error_list = obj.communicate('print "hello"') 
print out_error_list
View Code

10.python之正則表達式

經常使用正則表達式符號 

'.'     默認匹配除\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'    只從字符開頭匹配,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'}

 最經常使用的匹配語法

re.match 從頭開始匹配
re.search 匹配包含
re.findall 把全部匹配到的字符放到以列表中的元素返回
re.splitall 以匹配到的字符當作列表分隔符
re.sub      匹配字符並替換

 

反斜槓的困擾
與大多數編程語言相同,正則表達式裏使用"\"做爲轉義字符,這就可能形成反斜槓困擾。假如你須要匹配文本中的字符"\",那麼使用編程語言表示的正則表達式裏將須要4個反斜槓"\\\\":前兩個和後兩個分別用於在編程語言裏轉義成反斜槓,轉換成兩個反斜槓後再在正則表達式裏轉義成一個反斜槓。Python裏的原生字符串很好地解決了這個問題,這個例子中的正則表達式可使用r"\\"表示。一樣,匹配一個數字的"\\d"能夠寫成r"\d"。有了原生字符串,你不再用擔憂是否是漏寫了反斜槓,寫出來的表達式也更直觀。 

 

僅需輕輕知道的幾個匹配模式

re.I(re.IGNORECASE): 忽略大小寫(括號內是完整寫法,下同)
M(MULTILINE): 多行模式,改變'^'和'$'的行爲(參見上圖)
S(DOTALL): 點任意匹配模式,改變'.'的行爲

11.python之正則表達式之分組

12.XML模塊

瀏覽器返回的字符串類型有如下三種:

  • HTML
  • JSON
  • XML      1. 可作頁面展現; 2. 可作配置文件使用

 XML是實現不一樣語言或程序之間進行數據交換的協議,XML文件格式以下:

<data>
    <country name="Liechtenstein">
        <rank updated="yes">2</rank>
        <year>2023</year>
        <gdppc>141100</gdppc>
        <neighbor direction="E" name="Austria" />
        <neighbor direction="W" name="Switzerland" />
    </country>
    <country name="Singapore">
        <rank updated="yes">5</rank>
        <year>2026</year>
        <gdppc>59900</gdppc>
        <neighbor direction="N" name="Malaysia" />
    </country>
    <country name="Panama">
        <rank updated="yes">69</rank>
        <year>2026</year>
        <gdppc>13600</gdppc>
        <neighbor direction="W" name="Costa Rica" />
        <neighbor direction="E" name="Colombia" />
    </country>
</data>
XML文件格式

1. 解析XML 

from xml.etree import ElementTree as ET


# 打開文件,讀取XML內容
str_xml = open('xo.xml', 'r').read()

# 將字符串解析成xml特殊對象,root代指xml文件的根節點
root = ET.XML(str_xml)
利用ElementTree.XML將字符串解析成xml對象
from xml.etree import ElementTree as ET

# 直接解析xml文件,把文件加載到特殊對象tree中
tree = ET.parse("xo.xml")

# 獲取xml文件的根節點
root = tree.getroot()
View Code

2. 操做XML

XML格式類型是節點嵌套節點,對於每個節點均有如下功能,以便對當前節點進行操做: 

class Element:
    """An XML element.

    This class is the reference implementation of the Element interface.

    An element's length is its number of subelements.  That means if you
    want to check if an element is truly empty, you should check BOTH
    its length AND its text attribute.

    The element tag, attribute names, and attribute values can be either
    bytes or strings.

    *tag* is the element name.  *attrib* is an optional dictionary containing
    element attributes. *extra* are additional element attributes given as
    keyword arguments.

    Example form:
        <tag attrib>text<child/>...</tag>tail

    """

    當前節點的標籤名
    tag = None
    """The element's name."""

    當前節點的屬性

    attrib = None
    """Dictionary of the element's attributes."""

    當前節點的內容
    text = None
    """
    Text before first subelement. This is either a string or the value None.
    Note that if there is no text, this attribute may be either
    None or the empty string, depending on the parser.

    """

    tail = None
    """
    Text after this element's end tag, but before the next sibling element's
    start tag.  This is either a string or the value None.  Note that if there
    was no text, this attribute may be either None or an empty string,
    depending on the parser.

    """

    def __init__(self, tag, attrib={}, **extra):
        if not isinstance(attrib, dict):
            raise TypeError("attrib must be dict, not %s" % (
                attrib.__class__.__name__,))
        attrib = attrib.copy()
        attrib.update(extra)
        self.tag = tag
        self.attrib = attrib
        self._children = []

    def __repr__(self):
        return "<%s %r at %#x>" % (self.__class__.__name__, self.tag, id(self))

    def makeelement(self, tag, attrib):
        建立一個新節點
        """Create a new element with the same type.

        *tag* is a string containing the element name.
        *attrib* is a dictionary containing the element attributes.

        Do not call this method, use the SubElement factory function instead.

        """
        return self.__class__(tag, attrib)

    def copy(self):
        """Return copy of current element.

        This creates a shallow copy. Subelements will be shared with the
        original tree.

        """
        elem = self.makeelement(self.tag, self.attrib)
        elem.text = self.text
        elem.tail = self.tail
        elem[:] = self
        return elem

    def __len__(self):
        return len(self._children)

    def __bool__(self):
        warnings.warn(
            "The behavior of this method will change in future versions.  "
            "Use specific 'len(elem)' or 'elem is not None' test instead.",
            FutureWarning, stacklevel=2
            )
        return len(self._children) != 0 # emulate old behaviour, for now

    def __getitem__(self, index):
        return self._children[index]

    def __setitem__(self, index, element):
        # if isinstance(index, slice):
        #     for elt in element:
        #         assert iselement(elt)
        # else:
        #     assert iselement(element)
        self._children[index] = element

    def __delitem__(self, index):
        del self._children[index]

    def append(self, subelement):
        爲當前節點追加一個子節點
        """Add *subelement* to the end of this element.

        The new element will appear in document order after the last existing
        subelement (or directly after the text, if it's the first subelement),
        but before the end tag for this element.

        """
        self._assert_is_element(subelement)
        self._children.append(subelement)

    def extend(self, elements):
        爲當前節點擴展 n 個子節點
        """Append subelements from a sequence.

        *elements* is a sequence with zero or more elements.

        """
        for element in elements:
            self._assert_is_element(element)
        self._children.extend(elements)

    def insert(self, index, subelement):
        在當前節點的子節點中插入某個節點,即:爲當前節點建立子節點,而後插入指定位置
        """Insert *subelement* at position *index*."""
        self._assert_is_element(subelement)
        self._children.insert(index, subelement)

    def _assert_is_element(self, e):
        # Need to refer to the actual Python implementation, not the
        # shadowing C implementation.
        if not isinstance(e, _Element_Py):
            raise TypeError('expected an Element, not %s' % type(e).__name__)

    def remove(self, subelement):
        在當前節點在子節點中刪除某個節點
        """Remove matching subelement.

        Unlike the find methods, this method compares elements based on
        identity, NOT ON tag value or contents.  To remove subelements by
        other means, the easiest way is to use a list comprehension to
        select what elements to keep, and then use slice assignment to update
        the parent element.

        ValueError is raised if a matching element could not be found.

        """
        # assert iselement(element)
        self._children.remove(subelement)

    def getchildren(self):
        獲取全部的子節點(廢棄)
        """(Deprecated) Return all subelements.

        Elements are returned in document order.

        """
        warnings.warn(
            "This method will be removed in future versions.  "
            "Use 'list(elem)' or iteration over elem instead.",
            DeprecationWarning, stacklevel=2
            )
        return self._children

    def find(self, path, namespaces=None):
        獲取第一個尋找到的子節點
        """Find first matching element by tag name or path.

        *path* is a string having either an element tag or an XPath,
        *namespaces* is an optional mapping from namespace prefix to full name.

        Return the first matching element, or None if no element was found.

        """
        return ElementPath.find(self, path, namespaces)

    def findtext(self, path, default=None, namespaces=None):
        獲取第一個尋找到的子節點的內容
        """Find text for first matching element by tag name or path.

        *path* is a string having either an element tag or an XPath,
        *default* is the value to return if the element was not found,
        *namespaces* is an optional mapping from namespace prefix to full name.

        Return text content of first matching element, or default value if
        none was found.  Note that if an element is found having no text
        content, the empty string is returned.

        """
        return ElementPath.findtext(self, path, default, namespaces)

    def findall(self, path, namespaces=None):
        獲取全部的子節點
        """Find all matching subelements by tag name or path.

        *path* is a string having either an element tag or an XPath,
        *namespaces* is an optional mapping from namespace prefix to full name.

        Returns list containing all matching elements in document order.

        """
        return ElementPath.findall(self, path, namespaces)

    def iterfind(self, path, namespaces=None):
        獲取全部指定的節點,並建立一個迭代器(能夠被for循環)
        """Find all matching subelements by tag name or path.

        *path* is a string having either an element tag or an XPath,
        *namespaces* is an optional mapping from namespace prefix to full name.

        Return an iterable yielding all matching elements in document order.

        """
        return ElementPath.iterfind(self, path, namespaces)

    def clear(self):
        清空節點
        """Reset element.

        This function removes all subelements, clears all attributes, and sets
        the text and tail attributes to None.

        """
        self.attrib.clear()
        self._children = []
        self.text = self.tail = None

    def get(self, key, default=None):
        獲取當前節點的屬性值
        """Get element attribute.

        Equivalent to attrib.get, but some implementations may handle this a
        bit more efficiently.  *key* is what attribute to look for, and
        *default* is what to return if the attribute was not found.

        Returns a string containing the attribute value, or the default if
        attribute was not found.

        """
        return self.attrib.get(key, default)

    def set(self, key, value):
        爲當前節點設置屬性值
        """Set element attribute.

        Equivalent to attrib[key] = value, but some implementations may handle
        this a bit more efficiently.  *key* is what attribute to set, and
        *value* is the attribute value to set it to.

        """
        self.attrib[key] = value

    def keys(self):
        獲取當前節點的全部屬性的 key

        """Get list of attribute names.

        Names are returned in an arbitrary order, just like an ordinary
        Python dict.  Equivalent to attrib.keys()

        """
        return self.attrib.keys()

    def items(self):
        獲取當前節點的全部屬性值,每一個屬性都是一個鍵值對
        """Get element attributes as a sequence.

        The attributes are returned in arbitrary order.  Equivalent to
        attrib.items().

        Return a list of (name, value) tuples.

        """
        return self.attrib.items()

    def iter(self, tag=None):
        在當前節點的子孫中根據節點名稱尋找全部指定的節點,並返回一個迭代器(能夠被for循環)。
        """Create tree iterator.

        The iterator loops over the element and all subelements in document
        order, returning all elements with a matching tag.

        If the tree structure is modified during iteration, new or removed
        elements may or may not be included.  To get a stable set, use the
        list() function on the iterator, and loop over the resulting list.

        *tag* is what tags to look for (default is to return all elements)

        Return an iterator containing all the matching elements.

        """
        if tag == "*":
            tag = None
        if tag is None or self.tag == tag:
            yield self
        for e in self._children:
            yield from e.iter(tag)

    # compatibility
    def getiterator(self, tag=None):
        # Change for a DeprecationWarning in 1.4
        warnings.warn(
            "This method will be removed in future versions.  "
            "Use 'elem.iter()' or 'list(elem.iter())' instead.",
            PendingDeprecationWarning, stacklevel=2
        )
        return list(self.iter(tag))

    def itertext(self):
        在當前節點的子孫中根據節點名稱尋找全部指定的節點的內容,並返回一個迭代器(能夠被for循環)。
        """Create text iterator.

        The iterator loops over the element and all subelements in document
        order, returning all inner text.

        """
        tag = self.tag
        if not isinstance(tag, str) and tag is not None:
            return
        if self.text:
            yield self.text
        for e in self:
            yield from e.itertext()
            if e.tail:
                yield e.tail
節點功能一覽表 

因爲 每一個節點 都具備以上的方法,而且在上一步驟中解析時均獲得了root(xml文件的根節點),so   能夠利用以上方法進行操做xml文件。

a. 遍歷XML文檔的全部內容

from xml.etree import ElementTree as ET

############ 解析方式一 ############
"""
# 打開文件,讀取XML內容
str_xml = open('xo.xml', 'r').read()

# 將字符串解析成xml特殊對象,root代指xml文件的根節點
root = ET.XML(str_xml)
"""
############ 解析方式二 ############

# 直接解析xml文件
tree = ET.parse("xo.xml")

# 獲取xml文件的根節點
root = tree.getroot()


### 操做

# 頂層標籤
print(root.tag)


# 遍歷XML文檔的第二層
for child in root:
    # 第二層節點的標籤名稱和標籤屬性
    print(child.tag, child.attrib)
    # 遍歷XML文檔的第三層
    for i in child:
        # 第二層節點的標籤名稱和內容
        print(i.tag,i.text)
View Code

b、遍歷XML中指定的節點 

from xml.etree import ElementTree as ET

############ 解析方式一 ############
"""
# 打開文件,讀取XML內容
str_xml = open('xo.xml', 'r').read()

# 將字符串解析成xml特殊對象,root代指xml文件的根節點
root = ET.XML(str_xml)
"""
############ 解析方式二 ############

# 直接解析xml文件
tree = ET.parse("xo.xml")

# 獲取xml文件的根節點
root = tree.getroot()


### 操做

# 頂層標籤
print(root.tag)


# 遍歷XML中全部的year節點
for node in root.iter('year'):
    # 節點的標籤名稱和內容
    print(node.tag, node.text)
View Code

c、修改節點內容 

因爲修改的節點時,均是在內存中進行,其不會影響文件中的內容。因此,若是想要修改,則須要從新將內存中的內容寫到文件。

from xml.etree import ElementTree as ET

############ 解析方式一 ############

# 打開文件,讀取XML內容
str_xml = open('xo.xml', 'r').read()

# 將字符串解析成xml特殊對象,root代指xml文件的根節點
root = ET.XML(str_xml)

############ 操做 ############

# 頂層標籤
print(root.tag)

# 循環全部的year節點
for node in root.iter('year'):
    # 將year節點中的內容自增一
    new_year = int(node.text) + 1
    node.text = str(new_year)

    # 設置屬性
    node.set('name', 'alex')
    node.set('age', '18')
    # 刪除屬性
    del node.attrib['name']


############ 保存文件 ############
tree = ET.ElementTree(root)
tree.write("newnew.xml", encoding='utf-8')
解析字符串方式,修改,保存
from xml.etree import ElementTree as ET

############ 解析方式二 ############

# 直接解析xml文件
tree = ET.parse("xo.xml")

# 獲取xml文件的根節點
root = tree.getroot()

############ 操做 ############

# 頂層標籤
print(root.tag)

# 循環全部的year節點
for node in root.iter('year'):
    # 將year節點中的內容自增一
    new_year = int(node.text) + 1
    node.text = str(new_year)

    # 設置屬性
    node.set('name', 'alex')
    node.set('age', '18')
    # 刪除屬性
    del node.attrib['name']


############ 保存文件 ############
tree.write("newnew.xml", encoding='utf-8')
解析文件方式,修改,保存

d、刪除節點

from xml.etree import ElementTree as ET

############ 解析字符串方式打開 ############

# 打開文件,讀取XML內容
str_xml = open('xo.xml', 'r').read()

# 將字符串解析成xml特殊對象,root代指xml文件的根節點
root = ET.XML(str_xml)

############ 操做 ############

# 頂層標籤
print(root.tag)

# 遍歷data下的全部country節點
for country in root.findall('country'):
    # 獲取每個country節點下rank節點的內容
    rank = int(country.find('rank').text)

    if rank > 50:
        # 刪除指定country節點
        root.remove(country)

############ 保存文件 ############
tree = ET.ElementTree(root)
tree.write("newnew.xml", encoding='utf-8')
解析字符串方式打開,刪除,保存
from xml.etree import ElementTree as ET

############ 解析文件方式 ############

# 直接解析xml文件
tree = ET.parse("xo.xml")

# 獲取xml文件的根節點
root = tree.getroot()

############ 操做 ############

# 頂層標籤
print(root.tag)

# 遍歷data下的全部country節點
for country in root.findall('country'):
    # 獲取每個country節點下rank節點的內容
    rank = int(country.find('rank').text)

    if rank > 50:
        # 刪除指定country節點
        root.remove(country)

############ 保存文件 ############
tree.write("newnew.xml", encoding='utf-8')
解析文件方式打開,刪除,保存  

3. 建立XML文檔

from xml.etree import ElementTree as ET


# 建立根節點
root = ET.Element("famliy")


# 建立節點大兒子
son1 = ET.Element('son', {'name': '兒1'})
# 建立小兒子
son2 = ET.Element('son', {"name": '兒2'})

# 在大兒子中建立兩個孫子
grandson1 = ET.Element('grandson', {'name': '兒11'})
grandson2 = ET.Element('grandson', {'name': '兒12'})
son1.append(grandson1)
son1.append(grandson2)


# 把兒子添加到根節點中
root.append(son1)
root.append(son1)

tree = ET.ElementTree(root)
tree.write('oooo.xml',encoding='utf-8', short_empty_elements=False)
建立方式1
from xml.etree import ElementTree as ET

# 建立根節點
root = ET.Element("famliy")


# 建立大兒子
# son1 = ET.Element('son', {'name': '兒1'})
son1 = root.makeelement('son', {'name': '兒1'})
# 建立小兒子
# son2 = ET.Element('son', {"name": '兒2'})
son2 = root.makeelement('son', {"name": '兒2'})

# 在大兒子中建立兩個孫子
# grandson1 = ET.Element('grandson', {'name': '兒11'})
grandson1 = son1.makeelement('grandson', {'name': '兒11'})
# grandson2 = ET.Element('grandson', {'name': '兒12'})
grandson2 = son1.makeelement('grandson', {'name': '兒12'})

son1.append(grandson1)
son1.append(grandson2)


# 把兒子添加到根節點中
root.append(son1)
root.append(son1)

tree = ET.ElementTree(root)
tree.write('oooo.xml',encoding='utf-8', short_empty_elements=False)
建立方式2
from xml.etree import ElementTree as ET


# 建立根節點
root = ET.Element("famliy")


# 建立節點大兒子
son1 = ET.SubElement(root, "son", attrib={'name': '兒1'})
# 建立小兒子
son2 = ET.SubElement(root, "son", attrib={"name": "兒2"})

# 在大兒子中建立一個孫子
grandson1 = ET.SubElement(son1, "age", attrib={'name': '兒11'})
grandson1.text = '孫子'


et = ET.ElementTree(root)  #生成文檔對象
et.write("test.xml", encoding="utf-8", xml_declaration=True, short_empty_elements=False)
建立方式3

因爲原生保存的XML時默認無縮進,若是想要設置縮進的話, 須要修改保存方式:

from xml.etree import ElementTree as ET
from xml.dom import minidom


def prettify(elem):
    """將節點轉換成字符串,並添加縮進。
    """
    rough_string = ET.tostring(elem, 'utf-8')
    reparsed = minidom.parseString(rough_string)
    return reparsed.toprettyxml(indent="\t")

# 建立根節點
root = ET.Element("famliy")


# 建立大兒子
# son1 = ET.Element('son', {'name': '兒1'})
son1 = root.makeelement('son', {'name': '兒1'})
# 建立小兒子
# son2 = ET.Element('son', {"name": '兒2'})
son2 = root.makeelement('son', {"name": '兒2'})

# 在大兒子中建立兩個孫子
# grandson1 = ET.Element('grandson', {'name': '兒11'})
grandson1 = son1.makeelement('grandson', {'name': '兒11'})
# grandson2 = ET.Element('grandson', {'name': '兒12'})
grandson2 = son1.makeelement('grandson', {'name': '兒12'})

son1.append(grandson1)
son1.append(grandson2)


# 把兒子添加到根節點中
root.append(son1)
root.append(son1)


raw_str = prettify(root)

f = open("xxxoo.xml",'w',encoding='utf-8')
f.write(raw_str)
f.close()
View Code

13.本週做業

相關文章
相關標籤/搜索