程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> Python >> python內置模塊(3)

python內置模塊(3)

編輯:Python

博主所有python文章均為python3.5.1環境。

目錄:

1.collection

2.subprocess

3.configparser

4.XML

5.shutil

一、 collection

  collection模塊提供了一些特殊的數據結構類型,在某些場景下有著非常神奇的功效。

1、計數器(counter)

Counter是對字典類型的補充,用於追蹤值的出現次數。

ps:具備字典的所有功能 + 自己的功能

c = Counter('abcdeabcdabcaba')
print c
輸出:Counter({'a': 5, 'b': 4, 'c': 3, 'd': 2, 'e': 1})
 ########################################################################
 ###  Counter
 ########################################################################
 
 class Counter(dict):
     '''Dict subclass for counting hashable items.  Sometimes called a bag
     or multiset.  Elements are stored as dictionary keys and their counts
     are stored as dictionary values.
 
     >>> c = Counter('abcdeabcdabcaba')  # count elements from a string
 
     >>> c.most_common(3)                # three most common elements
     [('a', 5), ('b', 4), ('c', 3)]
     >>> sorted(c)                       # list all unique elements
     ['a', 'b', 'c', 'd', 'e']
     >>> ''.join(sorted(c.elements()))   # list elements with repetitions
     'aaaaabbbbcccdde'
     >>> sum(c.values())                 # total of all counts
 
     >>> c['a']                          # count of letter 'a'
     >>> for elem in 'shazam':           # update counts from an iterable
     ...     c[elem] += 1                # by adding 1 to each element's count
     >>> c['a']                          # now there are seven 'a'
     >>> del c['b']                      # remove all 'b'
     >>> c['b']                          # now there are zero 'b'
 
     >>> d = Counter('simsalabim')       # make another counter
     >>> c.update(d)                     # add in the second counter
     >>> c['a']                          # now there are nine 'a'
 
     >>> c.clear()                       # empty the counter
     >>> c
     Counter()
 
     Note:  If a count is set to zero or reduced to zero, it will remain
     in the counter until the entry is deleted or the counter is cleared:
 
     >>> c = Counter('aaabbc')
     >>> c['b'] -= 2                     # reduce the count of 'b' by two
     >>> c.most_common()                 # 'b' is still in, but its count is zero
     [('a', 3), ('c', 1), ('b', 0)]
 
     '''
     # References:
     #   http://en.wikipedia.org/wiki/Multiset
     #   http://www.gnu.org/software/smalltalk/manual-base/html_node/Bag.html
     #   http://www.demo2s.com/Tutorial/Cpp/0380__set-multiset/Catalog0380__set-multiset.htm
     #   http://code.activestate.com/recipes/259174/
     #   Knuth, TAOCP Vol. II section 4.6.3
 
     def __init__(self, iterable=None, **kwds):
         '''Create a new, empty Counter object.  And if given, count elements
         from an input iterable.  Or, initialize the count from another mapping
         of elements to their counts.
 
         >>> c = Counter()                           # a new, empty counter
         >>> c = Counter('gallahad')                 # a new counter from an iterable
         >>> c = Counter({'a': 4, 'b': 2})           # a new counter from a mapping
         >>> c = Counter(a=4, b=2)                   # a new counter from keyword args
 
         '''
         super(Counter, self).__init__()
         self.update(iterable, **kwds)
 
     def __missing__(self, key):
         """ 對於不存在的元素,返回計數器為0 """
         'The count of elements not in the Counter is zero.'
         # Needed so that self[missing_item] does not raise KeyError
         return 0
 
     def most_common(self, n=None):
         """ 數量大於等n的所有元素和計數器 """
         '''List the n most common elements and their counts from the most
         common to the least.  If n is None, then list all element counts.
 
         >>> Counter('abcdeabcdabcaba').most_common(3)
         [('a', 5), ('b', 4), ('c', 3)]
 
         '''
         # Emulate Bag.sortedByCount from Smalltalk
         if n is None:
             return sorted(self.iteritems(), key=_itemgetter(1), reverse=True)
         return _heapq.nlargest(n, self.iteritems(), key=_itemgetter(1))
 
     def elements(self):
         """ 計數器中的所有元素,注:此處非所有元素集合,而是包含所有元素集合的迭代器 """
         '''Iterator over elements repeating each as many times as its count.
 
         >>> c = Counter('ABCABC')
         >>> sorted(c.elements())
         ['A', 'A', 'B', 'B', 'C', 'C']
 
         # Knuth's example for prime factors of 1836:  2**2 * 3**3 * 17**1
         >>> prime_factors = Counter({2: 2, 3: 3, 17: 1})
         >>> product = 1
         >>> for factor in prime_factors.elements():     # loop over factors
         ...     product *= factor                       # and multiply them
         >>> product
 
         Note, if an element's count has been set to zero or is a negative
         number, elements() will ignore it.
 
         '''
         # Emulate Bag.do from Smalltalk and Multiset.begin from C++.
         return _chain.from_iterable(_starmap(_repeat, self.iteritems()))
 
     # Override dict methods where necessary
 
     @classmethod
     def fromkeys(cls, iterable, v=None):
         # There is no equivalent method for counters because setting v=1
         # means that no element can have a count greater than one.
         raise NotImplementedError(
             'Counter.fromkeys() is undefined.  Use Counter(iterable) instead.')
 
     def update(self, iterable=None, **kwds):
         """ 更新計數器,其實就是增加;如果原來沒有,則新建,如果有則加一 """
         '''Like dict.update() but add counts instead of replacing them.
 
         Source can be an iterable, a dictionary, or another Counter instance.
 
         >>> c = Counter('which')
         >>> c.update('witch')           # add elements from another iterable
         >>> d = Counter('watch')
         >>> c.update(d)                 # add elements from another counter
         >>> c['h']                      # four 'h' in which, witch, and watch
 
         '''
         # The regular dict.update() operation makes no sense here because the
         # replace behavior results in the some of original untouched counts
         # being mixed-in with all of the other counts for a mismash that
         # doesn't have a straight-forward interpretation in most counting
         # contexts.  Instead, we implement straight-addition.  Both the inputs
         # and outputs are allowed to contain zero and negative counts.
 
         if iterable is not None:
             if isinstance(iterable, Mapping):
                 if self:
                     self_get = self.get
                     for elem, count in iterable.iteritems():
                         self[elem] = self_get(elem, 0) + count
                 else:
                     super(Counter, self).update(iterable) # fast path when counter is empty
             else:
                 self_get = self.get
                 for elem in iterable:
                     self[elem] = self_get(elem, 0) + 1
         if kwds:
             self.update(kwds)
 
     def subtract(self, iterable=None, **kwds):
         """ 相減,原來的計數器中的每一個元素的數量減去後添加的元素的數量 """
         '''Like dict.update() but subtracts counts instead of replacing them.
         Counts can be reduced below zero.  Both the inputs and outputs are
         allowed to contain zero and negative counts.
 
         Source can be an iterable, a dictionary, or another Counter instance.
 
         >>> c = Counter('which')
         >>> c.subtract('witch')             # subtract elements from another iterable
         >>> c.subtract(Counter('watch'))    # subtract elements from another counter
         >>> c['h']                          # 2 in which, minus 1 in witch, minus 1 in watch
         >>> c['w']                          # 1 in which, minus 1 in witch, minus 1 in watch
         -1
 
         '''
         if iterable is not None:
             self_get = self.get
             if isinstance(iterable, Mapping):
                 for elem, count in iterable.items():
                     self[elem] = self_get(elem, 0) - count
             else:
                 for elem in iterable:
                     self[elem] = self_get(elem, 0) - 1
         if kwds:
             self.subtract(kwds)
 
     def copy(self):
         """ 拷貝 """
         'Return a shallow copy.'
         return self.__class__(self)
 
     def __reduce__(self):
         """ 返回一個元組(類型,元組) """
         return self.__class__, (dict(self),)
 
     def __delitem__(self, elem):
         """ 刪除元素 """
         'Like dict.__delitem__() but does not raise KeyError for missing values.'
         if elem in self:
             super(Counter, self).__delitem__(elem)
 
     def __repr__(self):
         if not self:
             return '%s()' % self.__class__.__name__
         items = ', '.join(map('%r: %r'.__mod__, self.most_common()))
         return '%s({%s})' % (self.__class__.__name__, items)
 
     # Multiset-style mathematical operations discussed in:
     #       Knuth TAOCP Volume II section 4.6.3 exercise 19
     #       and at http://en.wikipedia.org/wiki/Multiset
     #
     # Outputs guaranteed to only include positive counts.
     #
     # To strip negative and zero counts, add-in an empty counter:
     #       c += Counter()
 
     def __add__(self, other):
         '''Add counts from two counters.
 
         >>> Counter('abbb') + Counter('bcc')
         Counter({'b': 4, 'c': 2, 'a': 1})
 
         '''
         if not isinstance(other, Counter):
             return NotImplemented
         result = Counter()
         for elem, count in self.items():
             newcount = count + other[elem]
             if newcount > 0:
                 result[elem] = newcount
         for elem, count in other.items():
             if elem not in self and count > 0:
                 result[elem] = count
         return result
 
     def __sub__(self, other):
         ''' Subtract count, but keep only results with positive counts.
 
         >>> Counter('abbbc') - Counter('bccd')
         Counter({'b': 2, 'a': 1})
 
         '''
         if not isinstance(other, Counter):
             return NotImplemented
         result = Counter()
         for elem, count in self.items():
             newcount = count - other[elem]
             if newcount > 0:
                 result[elem] = newcount
         for elem, count in other.items():
             if elem not in self and count < 0:
                 result[elem] = 0 - count
         return result
 
     def __or__(self, other):
         '''Union is the maximum of value in either of the input counters.
 
         >>> Counter('abbb') | Counter('bcc')
         Counter({'b': 3, 'c': 2, 'a': 1})
 
         '''
         if not isinstance(other, Counter):
             return NotImplemented
         result = Counter()
         for elem, count in self.items():
             other_count = other[elem]
             newcount = other_count if count < other_count else count
             if newcount > 0:
                 result[elem] = newcount
         for elem, count in other.items():
             if elem not in self and count > 0:
                 result[elem] = count
         return result
 
     def __and__(self, other):
         ''' Intersection is the minimum of corresponding counts.
 
         >>> Counter('abbb') & Counter('bcc')
         Counter({'b': 1})
 
         '''
         if not isinstance(other, Counter):
             return NotImplemented
         result = Counter()
         for elem, count in self.items():
             other_count = other[elem]
             newcount = count if count < other_count else other_count
             if newcount > 0:
                 result[elem] = newcount
         return result
 
 Counter
 
 Counter
counter

2、有序字典(orderedDict )

orderdDict是對字典類型的補充,他記住了字典元素添加的順序

 class OrderedDict(dict):
     'Dictionary that remembers insertion order'
     # An inherited dict maps keys to values.
     # The inherited dict provides __getitem__, __len__, __contains__, and get.
     # The remaining methods are order-aware.
     # Big-O running times for all methods are the same as regular dictionaries.
 
     # The internal self.__map dict maps keys to links in a doubly linked list.
     # The circular doubly linked list starts and ends with a sentinel element.
     # The sentinel element never gets deleted (this simplifies the algorithm).
     # Each link is stored as a list of length three:  [PREV, NEXT, KEY].
 
     def __init__(self, *args, **kwds):
         '''Initialize an ordered dictionary.  The signature is the same as
         regular dictionaries, but keyword arguments are not recommended because
         their insertion order is arbitrary.
 
         '''
         if len(args) > 1:
             raise TypeError('expected at most 1 arguments, got %d' % len(args))
         try:
             self.__root
         except AttributeError:
             self.__root = root = []                     # sentinel node
             root[:] = [root, root, None]
             self.__map = {}
         self.__update(*args, **kwds)
 
     def __setitem__(self, key, value, dict_setitem=dict.__setitem__):
         'od.__setitem__(i, y) <==> od[i]=y'
         # Setting a new item creates a new link at the end of the linked list,
         # and the inherited dictionary is updated with the new key/value pair.
         if key not in self:
             root = self.__root
             last = root[0]
             last[1] = root[0] = self.__map[key] = [last, root, key]
         return dict_setitem(self, key, value)
 
     def __delitem__(self, key, dict_delitem=dict.__delitem__):
         'od.__delitem__(y) <==> del od[y]'
         # Deleting an existing item uses self.__map to find the link which gets
         # removed by updating the links in the predecessor and successor nodes.
         dict_delitem(self, key)
         link_prev, link_next, _ = self.__map.pop(key)
         link_prev[1] = link_next                        # update link_prev[NEXT]
         link_next[0] = link_prev                        # update link_next[PREV]
 
     def __iter__(self):
         'od.__iter__() <==> iter(od)'
         # Traverse the linked list in order.
         root = self.__root
         curr = root[1]                                  # start at the first node
         while curr is not root:
             yield curr[2]                               # yield the curr[KEY]
             curr = curr[1]                              # move to next node
 
     def __reversed__(self):
         'od.__reversed__() <==> reversed(od)'
         # Traverse the linked list in reverse order.
         root = self.__root
         curr = root[0]                                  # start at the last node
         while curr is not root:
             yield curr[2]                               # yield the curr[KEY]
             curr = curr[0]                              # move to previous node
 
     def clear(self):
         'od.clear() -> None.  Remove all items from od.'
         root = self.__root
         root[:] = [root, root, None]
         self.__map.clear()
         dict.clear(self)
 
     # -- the following methods do not depend on the internal structure --
 
     def keys(self):
         'od.keys() -> list of keys in od'
         return list(self)
 
     def values(self):
         'od.values() -> list of values in od'
         return [self[key] for key in self]
 
     def items(self):
         'od.items() -> list of (key, value) pairs in od'
         return [(key, self[key]) for key in self]
 
     def iterkeys(self):
         'od.iterkeys() -> an iterator over the keys in od'
         return iter(self)
 
     def itervalues(self):
         'od.itervalues -> an iterator over the values in od'
         for k in self:
             yield self[k]
 
     def iteritems(self):
         'od.iteritems -> an iterator over the (key, value) pairs in od'
         for k in self:
             yield (k, self[k])
 
     update = MutableMapping.update
 
     __update = update # let subclasses override update without breaking __init__
 
     __marker = object()
 
     def pop(self, key, default=__marker):
         '''od.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.
 
         '''
         if key in self:
             result = self[key]
             del self[key]
             return result
         if default is self.__marker:
             raise KeyError(key)
         return default
 
     def setdefault(self, key, default=None):
         'od.setdefault(k[,d]) -> od.get(k,d), also set od[k]=d if k not in od'
         if key in self:
             return self[key]
         self[key] = default
         return default
 
     def popitem(self, last=True):
         '''od.popitem() -> (k, v), return and remove a (key, value) pair.
         Pairs are returned in LIFO order if last is true or FIFO order if false.
 
         '''
         if not self:
             raise KeyError('dictionary is empty')
         key = next(reversed(self) if last else iter(self))
         value = self.pop(key)
         return key, value
 
     def __repr__(self, _repr_running={}):
         'od.__repr__() <==> repr(od)'
         call_key = id(self), _get_ident()
         if call_key in _repr_running:
             return '...'
         _repr_running[call_key] = 1
         try:
             if not self:
                 return '%s()' % (self.__class__.__name__,)
             return '%s(%r)' % (self.__class__.__name__, self.items())
         finally:
             del _repr_running[call_key]
 
     def __reduce__(self):
         'Return state information for pickling'
         items = [[k, self[k]] for k in self]
         inst_dict = vars(self).copy()
         for k in vars(OrderedDict()):
             inst_dict.pop(k, None)
         if inst_dict:
             return (self.__class__, (items,), inst_dict)
         return self.__class__, (items,)
 
     def copy(self):
         'od.copy() -> a shallow copy of od'
         return self.__class__(self)
 
     @classmethod
     def fromkeys(cls, iterable, value=None):
         '''OD.fromkeys(S[, v]) -> New ordered dictionary with keys from S.
         If not specified, the value defaults to None.
 
         '''
         self = cls()
         for key in iterable:
             self[key] = value
         return self
 
     def __eq__(self, other):
         '''od.__eq__(y) <==> od==y.  Comparison to another OD is order-sensitive
         while comparison to a regular mapping is order-insensitive.
 
         '''
         if isinstance(other, OrderedDict):
             return dict.__eq__(self, other) and all(_imap(_eq, self, other))
         return dict.__eq__(self, other)
 
     def __ne__(self, other):
         'od.__ne__(y) <==> od!=y'
         return not self == other
 
     # -- the following methods support python 3.x style dictionary views --
 
     def viewkeys(self):
         "od.viewkeys() -> a set-like object providing a view on od's keys"
         return KeysView(self)
 
     def viewvalues(self):
         "od.viewvalues() -> an object providing a view on od's values"
         return ValuesView(self)
 
     def viewitems(self):
         "od.viewitems() -> a set-like object providing a view on od's items"
         return ItemsView(self)
 
 OrderedDict
orderedDict

3、默認字典(defaultdict) 

學前需求:

有如下值集合 [11,22,33,44,55,66,77,88,99,90...],將所有大於 66 的值保存至字典的第一個key中,將小於 66 的值保存至第二個key的值中。

即: {'k1': 大於66 'k2': 小於66} 原生字典解決辦法:
values = [11, 22, 33,44,55,66,77,88,99,90]

my_dict = {}

for value in  values:
    if value>66:
        if my_dict.has_key('k1'):
            my_dict['k1'].append(value)
        else:
            my_dict['k1'] = [value]
    else:
        if my_dict.has_key('k2'):
            my_dict['k2'].append(value)
        else:
            my_dict['k2'] = [value]

  默認字典解決辦法:

from collections import defaultdict

values = [11, 22, 33,44,55,66,77,88,99,90]

my_dict = defaultdict(list)

for value in  values:
    if value>66:
        my_dict['k1'].append(value)
    else:
        my_dict['k2'].append(value)

  defaultdict是對字典的類型的補充,他默認給字典的值設置了一個類型。

 class defaultdict(dict):
     """
     defaultdict(default_factory[, ...]) --> dict with default factory
     
     The default factory is called without arguments to produce
     a new value when a key is not present, in __getitem__ only.
     A defaultdict compares equal to a dict with the same items.
     All remaining arguments are treated the same as if they were
     passed to the dict constructor, including keyword arguments.
     """
     def copy(self): # real signature unknown; restored from __doc__
         """ D.copy() -> a shallow copy of D. """
         pass
 
     def __copy__(self, *args, **kwargs): # real signature unknown
         """ D.copy() -> a shallow copy of D. """
         pass
 
     def __getattribute__(self, name): # real signature unknown; restored from __doc__
         """ x.__getattribute__('name') <==> x.name """
         pass
 
     def __init__(self, default_factory=None, **kwargs): # known case of _collections.defaultdict.__init__
         """
         defaultdict(default_factory[, ...]) --> dict with default factory
         
         The default factory is called without arguments to produce
         a new value when a key is not present, in __getitem__ only.
         A defaultdict compares equal to a dict with the same items.
         All remaining arguments are treated the same as if they were
         passed to the dict constructor, including keyword arguments.
         
         # (copied from class doc)
         """
         pass
 
     def __missing__(self, key): # real signature unknown; restored from __doc__
         """
         __missing__(key) # Called by __getitem__ for missing key; pseudo-code:
           if self.default_factory is None: raise KeyError((key,))
           self[key] = value = self.default_factory()
           return value
         """
         pass
 
     def __reduce__(self, *args, **kwargs): # real signature unknown
         """ Return state information for pickling. """
         pass
 
     def __repr__(self): # real signature unknown; restored from __doc__
         """ x.__repr__() <==> repr(x) """
         pass
 
     default_factory = property(lambda self: object(), lambda self, v: None, lambda self: None)  # default
     """Factory for default value called by __missing__()."""
 
 defaultdict
defaultDict

4、可命名元組(namedtuple) 

根據nametuple可以創建一個包含tuple所有功能以及其他功能的類型 

import collections
 
Mytuple = collections.namedtuple('Mytuple',['x', 'y', 'z'])
 class Mytuple(__builtin__.tuple)
  |  Mytuple(x, y)
  |  
  |  Method resolution order:
  |      Mytuple
  |      __builtin__.tuple
  |      __builtin__.object
  |  
  |  Methods defined here:
  |  
  |  __getnewargs__(self)
  |      Return self as a plain tuple.  Used by copy and pickle.
  |  
  |  __getstate__(self)
  |      Exclude the OrderedDict from pickling
  |  
  |  __repr__(self)
  |      Return a nicely formatted representation string
  |  
  |  _asdict(self)
  |      Return a new OrderedDict which maps field names to their values
  |  
  |  _replace(_self, **kwds)
  |      Return a new Mytuple object replacing specified fields with new values
  |  
  |  ----------------------------------------------------------------------
  |  Class methods defined here:
  |  
  |  _make(cls, iterable, new=<built-in method __new__ of type object>, len=<built-in function len>) from __builtin__.type
  |      Make a new Mytuple object from a sequence or iterable
  |  
  |  ----------------------------------------------------------------------
  |  Static methods defined here:
  |  
  |  __new__(_cls, x, y)
  |      Create new instance of Mytuple(x, y)
  |  
  |  ----------------------------------------------------------------------
  |  Data descriptors defined here:
  |  
  |  __dict__
  |      Return a new OrderedDict which maps field names to their values
  |  
  |  x
  |      Alias for field number 0
  |  
  |  y
  |      Alias for field number 1
  |  
  |  ----------------------------------------------------------------------
  |  Data and other attributes defined here:
  |  
  |  _fields = ('x', 'y')
  |  
  |  ----------------------------------------------------------------------
  |  Methods inherited from __builtin__.tuple:
  |  
  |  __add__(...)
  |      x.__add__(y) <==> x+y
  |  
  |  __contains__(...)
  |      x.__contains__(y) <==> y in x
  |  
  |  __eq__(...)
  |      x.__eq__(y) <==> x==y
  |  
  |  __ge__(...)
  |      x.__ge__(y) <==> x>=y
  |  
  |  __getattribute__(...)
  |      x.__getattribute__('name') <==> x.name
  |  
  |  __getitem__(...)
  |      x.__getitem__(y) <==> x[y]
  |  
  |  __getslice__(...)
  |      x.__getslice__(i, j) <==> x[i:j]
  |      
  |      Use of negative indices is not supported.
  |  
  |  __gt__(...)
  |      x.__gt__(y) <==> x>y
  |  
  |  __hash__(...)
  |      x.__hash__() <==> hash(x)
  |  
  |  __iter__(...)
  |      x.__iter__() <==> iter(x)
  |  
  |  __le__(...)
  |      x.__le__(y) <==> x<=y
  |  
  |  __len__(...)
  |      x.__len__() <==> len(x)
  |  
  |  __lt__(...)
  |      x.__lt__(y) <==> x<y
  |  
  |  __mul__(...)
  |      x.__mul__(n) <==> x*n
  |  
  |  __ne__(...)
  |      x.__ne__(y) <==> x!=y
  |  
  |  __rmul__(...)
  |      x.__rmul__(n) <==> n*x
  |  
  |  __sizeof__(...)
  |      T.__sizeof__() -- size of T in memory, in bytes
  |  
  |  count(...)
  |      T.count(value) -> integer -- return number of occurrences of value
  |  
  |  index(...)
  |      T.index(value, [start, [stop]]) -> integer -- return first index of value.
  |      Raises ValueError if the value is not present.
 
 Mytuple
 
 Mytuple
namedtuple

5、雙向隊列(deque)

一個線程安全的雙向隊列

 class deque(object):
     """
     deque([iterable[, maxlen]]) --> deque object
     
     Build an ordered collection with optimized access from its endpoints.
     """
     def append(self, *args, **kwargs): # real signature unknown
         """ Add an element to the right side of the deque. """
         pass
 
     def appendleft(self, *args, **kwargs): # real signature unknown
         """ Add an element to the left side of the deque. """
         pass
 
     def clear(self, *args, **kwargs): # real signature unknown
         """ Remove all elements from the deque. """
         pass
 
     def count(self, value): # real signature unknown; restored from __doc__
         """ D.count(value) -> integer -- return number of occurrences of value """
         return 0
 
     def extend(self, *args, **kwargs): # real signature unknown
         """ Extend the right side of the deque with elements from the iterable """
         pass
 
     def extendleft(self, *args, **kwargs): # real signature unknown
         """ Extend the left side of the deque with elements from the iterable """
         pass
 
     def pop(self, *args, **kwargs): # real signature unknown
         """ Remove and return the rightmost element. """
         pass
 
     def popleft(self, *args, **kwargs): # real signature unknown
         """ Remove and return the leftmost element. """
         pass
 
     def remove(self, value): # real signature unknown; restored from __doc__
         """ D.remove(value) -- remove first occurrence of value. """
         pass
 
     def reverse(self): # real signature unknown; restored from __doc__
         """ D.reverse() -- reverse *IN PLACE* """
         pass
 
     def rotate(self, *args, **kwargs): # real signature unknown
         """ Rotate the deque n steps to the right (default n=1).  If n is negative, rotates left. """
         pass
 
     def __copy__(self, *args, **kwargs): # real signature unknown
         """ Return a shallow copy of a deque. """
         pass
 
     def __delitem__(self, y): # real signature unknown; restored from __doc__
         """ x.__delitem__(y) <==> del x[y] """
         pass
 
     def __eq__(self, y): # real signature unknown; restored from __doc__
         """ x.__eq__(y) <==> x==y """
         pass
 
     def __getattribute__(self, name): # real signature unknown; restored from __doc__
         """ x.__getattribute__('name') <==> x.name """
         pass
 
     def __getitem__(self, y): # real signature unknown; restored from __doc__
         """ x.__getitem__(y) <==> x[y] """
         pass
 
     def __ge__(self, y): # real signature unknown; restored from __doc__
         """ x.__ge__(y) <==> x>=y """
         pass
 
     def __gt__(self, y): # real signature unknown; restored from __doc__
         """ x.__gt__(y) <==> x>y """
         pass
 
     def __iadd__(self, y): # real signature unknown; restored from __doc__
         """ x.__iadd__(y) <==> x+=y """
         pass
 
     def __init__(self, iterable=(), maxlen=None): # known case of _collections.deque.__init__
         """
         deque([iterable[, maxlen]]) --> deque object
         
         Build an ordered collection with optimized access from its endpoints.
         # (copied from class doc)
         """
         pass
 
     def __iter__(self): # real signature unknown; restored from __doc__
         """ x.__iter__() <==> iter(x) """
         pass
 
     def __len__(self): # real signature unknown; restored from __doc__
         """ x.__len__() <==> len(x) """
         pass
 
     def __le__(self, y): # real signature unknown; restored from __doc__
         """ x.__le__(y) <==> x<=y """
         pass
 
     def __lt__(self, y): # real signature unknown; restored from __doc__
         """ x.__lt__(y) <==> x<y """
         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 __ne__(self, y): # real signature unknown; restored from __doc__
         """ x.__ne__(y) <==> x!=y """
         pass
 
     def __reduce__(self, *args, **kwargs): # real signature unknown
         """ Return state information for pickling. """
         pass
 
     def __repr__(self): # real signature unknown; restored from __doc__
         """ x.__repr__() <==> repr(x) """
         pass
 
     def __reversed__(self): # real signature unknown; restored from __doc__
         """ D.__reversed__() -- return a reverse iterator over the deque """
         pass
 
     def __setitem__(self, i, y): # real signature unknown; restored from __doc__
         """ x.__setitem__(i, y) <==> x[i]=y """
         pass
 
     def __sizeof__(self): # real signature unknown; restored from __doc__
         """ D.__sizeof__() -- size of D in memory, in bytes """
         pass
 
     maxlen = property(lambda self: object(), lambda self, v: None, lambda self: None)  # default
     """maximum size of a deque or None if unbounded"""
 
 
     __hash__ = None
 
 deque
deque

注:既然有雙向隊列,也有單項隊列(先進先出 FIFO )

 class Queue:
     """Create a queue object with a given maximum size.
 
     If maxsize is <= 0, the queue size is infinite.
     """
     def __init__(self, maxsize=0):
         self.maxsize = maxsize
         self._init(maxsize)
         # mutex must be held whenever the queue is mutating.  All methods
         # that acquire mutex must release it before returning.  mutex
         # is shared between the three conditions, so acquiring and
         # releasing the conditions also acquires and releases mutex.
         self.mutex = _threading.Lock()
         # Notify not_empty whenever an item is added to the queue; a
         # thread waiting to get is notified then.
         self.not_empty = _threading.Condition(self.mutex)
         # Notify not_full whenever an item is removed from the queue;
         # a thread waiting to put is notified then.
         self.not_full = _threading.Condition(self.mutex)
         # Notify all_tasks_done whenever the number of unfinished tasks
         # drops to zero; thread waiting to join() is notified to resume
         self.all_tasks_done = _threading.Condition(self.mutex)
         self.unfinished_tasks = 0
 
     def task_done(self):
         """Indicate that a formerly enqueued task is complete.
 
         Used by Queue consumer threads.  For each get() used to fetch a task,
         a subsequent call to task_done() tells the queue that the processing
         on the task is complete.
 
         If a join() is currently blocking, it will resume when all items
         have been processed (meaning that a task_done() call was received
         for every item that had been put() into the queue).
 
         Raises a ValueError if called more times than there were items
         placed in the queue.
         """
         self.all_tasks_done.acquire()
         try:
             unfinished = self.unfinished_tasks - 1
             if unfinished <= 0:
                 if unfinished < 0:
                     raise ValueError('task_done() called too many times')
                 self.all_tasks_done.notify_all()
             self.unfinished_tasks = unfinished
         finally:
             self.all_tasks_done.release()
 
     def join(self):
         """Blocks until all items in the Queue have been gotten and processed.
 
         The count of unfinished tasks goes up whenever an item is added to the
         queue. The count goes down whenever a consumer thread calls task_done()
         to indicate the item was retrieved and all work on it is complete.
 
         When the count of unfinished tasks drops to zero, join() unblocks.
         """
         self.all_tasks_done.acquire()
         try:
             while self.unfinished_tasks:
                 self.all_tasks_done.wait()
         finally:
             self.all_tasks_done.release()
 
     def qsize(self):
         """Return the approximate size of the queue (not reliable!)."""
         self.mutex.acquire()
         n = self._qsize()
         self.mutex.release()
         return n
 
     def empty(self):
         """Return True if the queue is empty, False otherwise (not reliable!)."""
         self.mutex.acquire()
         n = not self._qsize()
         self.mutex.release()
         return n
 
     def full(self):
         """Return True if the queue is full, False otherwise (not reliable!)."""
         self.mutex.acquire()
         n = 0 < self.maxsize == self._qsize()
         self.mutex.release()
         return n
 
     def put(self, item, block=True, timeout=None):
         """Put an item into the queue.
 
         If optional args 'block' is true and 'timeout' is None (the default),
         block if necessary until a free slot is available. If 'timeout' is
         a non-negative number, it blocks at most 'timeout' seconds and raises
         the Full exception if no free slot was available within that time.
         Otherwise ('block' is false), put an item on the queue if a free slot
         is immediately available, else raise the Full exception ('timeout'
         is ignored in that case).
         """
         self.not_full.acquire()
         try:
             if self.maxsize > 0:
                 if not block:
                     if self._qsize() == self.maxsize:
                         raise Full
                 elif timeout is None:
                     while self._qsize() == self.maxsize:
                         self.not_full.wait()
                 elif timeout < 0:
                     raise ValueError("'timeout' must be a non-negative number")
                 else:
                     endtime = _time() + timeout
                     while self._qsize() == self.maxsize:
                         remaining = endtime - _time()
                         if remaining <= 0.0:
                             raise Full
                         self.not_full.wait(remaining)
             self._put(item)
             self.unfinished_tasks += 1
             self.not_empty.notify()
         finally:
             self.not_full.release()
 
     def put_nowait(self, item):
         """Put an item into the queue without blocking.
 
         Only enqueue the item if a free slot is immediately available.
         Otherwise raise the Full exception.
         """
         return self.put(item, False)
 
     def get(self, block=True, timeout=None):
         """Remove and return an item from the queue.
 
         If optional args 'block' is true and 'timeout' is None (the default),
         block if necessary until an item is available. If 'timeout' is
         a non-negative number, it blocks at most 'timeout' seconds and raises
         the Empty exception if no item was available within that time.
         Otherwise ('block' is false), return an item if one is immediately
         available, else raise the Empty exception ('timeout' is ignored
         in that case).
         """
         self.not_empty.acquire()
         try:
             if not block:
                 if not self._qsize():
                     raise Empty
             elif timeout is None:
                 while not self._qsize():
                     self.not_empty.wait()
             elif timeout < 0:
                 raise ValueError("'timeout' must be a non-negative number")
             else:
                 endtime = _time() + timeout
                 while not self._qsize():
                     remaining = endtime - _time()
                     if remaining <= 0.0:
                         raise Empty
                     self.not_empty.wait(remaining)
             item = self._get()
             self.not_full.notify()
             return item
         finally:
             self.not_empty.release()
 
     def get_nowait(self):
         """Remove and return an item from the queue without blocking.
 
         Only get an item if one is immediately available. Otherwise
         raise the Empty exception.
         """
         return self.get(False)
 
     # Override these methods to implement other queue organizations
     # (e.g. stack or priority queue).
     # These will only be called with appropriate locks held
 
     # Initialize the queue representation
     def _init(self, maxsize):
         self.queue = deque()
 
     def _qsize(self, len=len):
         return len(self.queue)
 
     # Put a new item in the queue
     def _put(self, item):
         self.queue.append(item)
 
     # Get an item from the queue
     def _get(self):
         return self.queue.popleft()
 
 Queue.Queue
Queue

 二、subprocess

  如果你是做運維的,那麼這個模塊可能是用得最多的,它可以執行本地操作系統的相關命令。

  在python3之前可以執行shell命令的相關模塊和函數有:

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

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

call 

執行命令,返回狀態碼。經實際測試,shell=False這個參數已經不能用了,所以,無論你的命令字符串是怎麼的格式,都必須使用shell=True這個參數.

另外,還有一個run方法,可以替代call,使用方法和效果是一樣的。

ret = subprocess.call(["ls", "-l"], shell=False)  #已經廢棄
ret = subprocess.call("ls -l", shell=True)

check_call

執行命令,如果執行狀態碼是 0 ,則返回0,否則拋異常

import subprocess

ret = subprocess.check_call(["dir", "c:"], shell=True)
print(ret)

執行結果:
 C:\ ???¼

2015/12/13  12:31             3,488 bootsqm.dat
2015/10/19  00:43    <DIR>          Drivers
2015/11/02  19:43               164 log_followvideo.txt
2016/06/05  22:05    <DIR>          PerfLogs
2016/06/09  00:29    <DIR>          Program Files
2016/06/21  10:38    <DIR>          Program Files (x86)
2016/03/02  16:17    <DIR>          Python27
2016/05/20  09:56    <DIR>          Python35
2015/10/19  00:50    <DIR>          Users
2016/06/15  17:08    <DIR>          Windows
               2 ?????          3,652 ???
               8 ???¼ 21,048,045,568 ???????

0   #注意返回值是0,上面的是屏幕顯示

  

check_output

執行命令,如果狀態碼是 0 ,則返回執行結果,否則拋異常

import subprocess

ret = subprocess.check_output(["dir", "c:"], shell=True)
print(ret)

執行結果:
b' \xc7\xfd\xb6\xaf\xc6\xf7 C \xd6\xd0\xb5\xc4\xbe\xed\xca\xc7 \xcf\xb5\xcd\xb3\r\n \xbe\xed\xb5\xc4\xd0\xf2\xc1\xd0\xba\xc5\xca\xc7 C038-3181\r\n\r\n C:\\ \xb5\xc4\xc4\xbf\xc2\xbc\r\n\r\n2015/12/13  12:31             3,488 bootsqm.dat\r\n2015/10/19  00:43    <DIR>          Drivers\r\n2015/11/02  19:43               164 log_followvideo.txt\r\n2016/06/05  22:05    <DIR>          PerfLogs\r\n2016/06/09  00:29    <DIR>          Program Files\r\n2016/06/21  10:38    <DIR>          Program Files (x86)\r\n2016/03/02  16:17    <DIR>          Python27\r\n2016/05/20  09:56    <DIR>          Python35\r\n2015/10/19  00:50    <DIR>          Users\r\n2016/06/15  17:08    <DIR>          Windows\r\n               2 \xb8\xf6\xce\xc4\xbc\xfe          3,652 \xd7\xd6\xbd\xda\r\n               8 \xb8\xf6\xc4\xbf\xc2\xbc 21,050,003,456 \xbf\xc9\xd3\xc3\xd7\xd6\xbd\xda\r\n'



#返回結果是一個bytes類型的數據結構

 我們處理一下上面的返回結果:

import subprocess

ret = subprocess.check_output(["dir", "c:"], shell=True)
ret = ret.decode("GBK")
print(ret)

運行結果:

驅動器 C 中的卷是 系統
 卷的序列號是 C038-3181

 C:\ 的目錄

2015/12/13  12:31             3,488 bootsqm.dat
2015/10/19  00:43    <DIR>          Drivers
2015/11/02  19:43               164 log_followvideo.txt
2016/06/05  22:05    <DIR>          PerfLogs
2016/06/09  00:29    <DIR>          Program Files
2016/06/21  10:38    <DIR>          Program Files (x86)
2016/03/02  16:17    <DIR>          Python27
2016/05/20  09:56    <DIR>          Python35
2015/10/19  00:50    <DIR>          Users
2016/06/15  17:08    <DIR>          Windows
               2 個文件          3,652 字節
               8 個目錄 21,047,693,312 可用字節

subprocess.Popen(...)

用於執行復雜的系統命令。這個方法應該是subprocess模塊裡最核心的了。

參數:

    • 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

ret2 = subprocess.Popen("mkdir t2", shell=True)

由於終端中執行的命令有兩種,一種是立刻顯示結果的,一種是交互式環境的,在執行popen命令時要區別對待。

  • 輸入即可得到輸出,如:ifconfig
  • 輸入進行某環境,依賴再輸入,如:python
import subprocess

obj = subprocess.Popen("mkdir t3", shell=True, cwd='/home/dev',)

注意下面例子中,subprocess.PIPE的用法,和stdin,stdout,stderr的配合。  

import subprocess

obj = subprocess.Popen(["python"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
obj.stdin.write("print(1)\n")
obj.stdin.write("print(2)")
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)

 注意下面例子中的communicate方法,它可以將stdout和stderr的信息都保存起來。

import subprocess

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

out_error_list = obj.communicate()
print(out_error_list)

下面的例子進一步簡化了代碼,直接將命令作為參數傳遞給了communicate方法。 

import subprocess

obj = subprocess.Popen(["python"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
out_error_list = obj.communicate('print("hello")')
print(out_error_list)

三、configparser

做運維的同學對下面的文件格式一定不陌生:

[DEFAULT]
ServerAliveInterval = 45
Compression = yes
CompressionLevel = 9
ForwardX11 = yes
 
[bitbucket.org]
User = hg
 
[topsecret.server.com]
Port = 50022
ForwardX11 = no

configparser就是用於處理上面這種特定格式的文件,其本質上是利用open來操作文件。在python3以前,這個模塊叫configParser,注意大小寫。

將配置文件抽象一下:

# 注釋1
;  注釋2
 
[section1] # 節點
k1 = v1    # 值
k2:v2       # 值
 
[section2] # 節點
k1 = v1    # 值

如果想用python生成一個這樣的文檔怎麼做呢?(注意其中的default這個section,它是個默認設置,相當於其他section都包含了它裡面的內容)

import configparser
 
config = configparser.ConfigParser()
config["DEFAULT"] = {'ServerAliveInterval': '45',
                      'Compression': 'yes',
                     'CompressionLevel': '9'}
 
config['bitbucket.org'] = {}
config['bitbucket.org']['User'] = 'hg'
config['topsecret.server.com'] = {}
topsecret = config['topsecret.server.com']
topsecret['Host Port'] = '50022'     # mutates the parser
topsecret['ForwardX11'] = 'no'  # same here
config['DEFAULT']['ForwardX11'] = 'yes'
with open('example.ini', 'w') as configfile:
   config.write(configfile)

寫完了還可以再讀出來!

 >>> import configparser
 >>> config = configparser.ConfigParser()
 >>> config.sections()
 []
 >>> config.read('example.ini')
 ['example.ini']
 >>> config.sections()
 ['bitbucket.org', 'topsecret.server.com']
 >>> 'bitbucket.org' in config
 True
 >>> 'bytebong.com' in config
 False
 >>> config['bitbucket.org']['User']
 'hg'
 >>> config['DEFAULT']['Compression']
 'yes'
 >>> topsecret = config['topsecret.server.com']
 >>> topsecret['ForwardX11']
 'no'
 >>> topsecret['Port']
 '50022'
 >>> for key in config['bitbucket.org']: print(key)
 ...
 user
 compressionlevel
 serveraliveinterval
 compression
 forwardx11
 >>> config['bitbucket.org']['ForwardX11']
 'yes'
viewcode

configparser提供了豐富的增刪改查配置文件的方法:

1、獲取所有節點: sections()

import configparser
 
config = configparser.ConfigParser()
config.read('xxxooo', encoding='utf-8')
ret = config.sections()
print(ret)

2、獲取指定節點下所有的鍵值對:items("section")

import configparser
 
config = configparser.ConfigParser()
config.read('xxxooo', encoding='utf-8')
ret = config.items('section1')
print(ret

3、獲取指定節點下所有的鍵:options("section")  

import configparser
 
config = configparser.ConfigParser()
config.read('xxxooo', encoding='utf-8')
ret = config.options('section1')
print(ret)

4、獲取指定節點下指定key的值:get("section","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)

5、檢查、刪除、添加節點:

has_section("section")   add_section("section")    remove_section("section")

這些操作結束後都需要寫入文件,保存狀態,config.write(open("file","w")) 

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

6、檢查、刪除、設置指定組內的鍵值對:

has_option("section","key")    set("section","key","value")    remove_option("section","key")

注意:增加鍵值對不是add_option 而是set。

這些操作結束後都需要寫入文件,保存狀態,config.write(open("file","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'))

四、XML

xml是一種不同語言或程序之間進行數據交換的協議,跟json差不多,比json古老,相比之下json使用起來更簡單,因此逐漸被json替代。雖然如此,因為歷史和架構的原因很多傳統公司如金融行業的系統接口還主要是xml。

xml和html有點類似,都是通過<>節點來區別數據結構的,下面是一個例子:

 <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例子

由例子中可見,xml文件的每一個節點都可以有tag(標簽名 )、attrib(節點屬性)、text(節點內容)和子節點。最頂層的節點就是根節點。

所有的節點都被看做是一個Element類的實例。所有的操作也是以element元素為對象。

1.解析XML

有兩種方式解析XML。

a :利用ElementTree.XML將字符串解析成xml對象

from xml.etree import ElementTree as ET

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

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

b :利用ElementTree.parse將文件直接解析成xml對象

from xml.etree import ElementTree as ET

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

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

注意:在xml模塊裡,tree是一個很重要的類。上面兩種方法讀取xml文件後,在完成工作需要保存xml文件時都需要使用tree來保存。因此,a方法需要再生成一個tree對象,而b方法通過ET.parse直接就獲得了一個tree對象,並通過該對象的getroot方法獲得了xml文件的根節點。 

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文件的根節點),因此可以利用以上方法進行操作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、修改節點內容

由於修改的節點時,均是在內存中進行,不會影響文件中的內容。所以,如果想要保存修改操作,則需要重新將內存中的內容寫到文件。

下面是解析文件方式,直接獲得了tree,因此可以直接修改文件並保存。

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

解析文件方式,修改,保存
View Code

下面是解析字符串方式,由於沒有獲得tree,因此在保存的時候需要實例化一個tree對象。注意觀察代碼的最後兩行。

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

解析字符串方式,修改,保存
View Code

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)
創建方式(一)
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)
創建方式(二)
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)
創建方式(三)

由於原生保存的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()
自動縮進

4、命名空間

from xml.etree import ElementTree as ET

ET.register_namespace('com',"http://www.company.com") #some name

# build a tree structure
root = ET.Element("{http://www.company.com}STUFF")
body = ET.SubElement(root, "{http://www.company.com}MORE_STUFF", attrib={"{http://www.company.com}hhh": "123"})
body.text = "STUFF EVERYWHERE!"

# wrap it in an ElementTree instance, and save as XML
tree = ET.ElementTree(root)

tree.write("page.xml",
           xml_declaration=True,
           encoding='utf-8',
           method="xml")

命名空間
View Code

五、shutil

  shutil模塊是python為我們封裝的一個高級的高級的文件、文件夾、壓縮包 處理模塊,它本質上是調用open方法對文件進行讀寫。模塊相對比較簡單,記住幾個常用的方法即可。

1、shutil.copyfileobj(fsrc, fdst[, length])
將文件內容拷貝到另一個文件中。這個是基本方法,其他的拷貝方法都是在後台調用這個方法。 

import shutil
 
shutil.copyfileobj(open('old.xml','r'), open('new.xml', 'w'))

2、shutil.copyfile(src, dst)
拷貝文件 

shutil.copyfile('f1.log', 'f2.log')

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

shutil.copymode('f1.log', 'f2.log')

4、shutil.copystat(src, dst)
僅拷貝狀態的信息,包括:mode bits, atime, mtime, flags

shutil.copystat('f1.log', 'f2.log')

5、 shutil.copy(src, dst)
拷貝文件和權限

shutil.copy('f1.log', 'f2.log')

6、shutil.copy2(src, dst)
拷貝文件和狀態信息 

shutil.copy2('f1.log', 'f2.log')

7、shutil.ignore_patterns(*patterns)

shutil.copytree(src, dst, symlinks=False, ignore=None)
遞歸的去拷貝文件夾。ignor_patterns是指忽略不拷貝的文件

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

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

shutil.rmtree('folder1')

9、shutil.move(src, dst)
遞歸的去移動文件,它類似mv命令,其實就是重命名。 

shutil.move('folder1', 'folder3')

10、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 兩個模塊來進行的,但封裝的比較簡單,不是很好用,建議還是使用ZipFile 和 TarFile 模塊。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved