zoukankan      html  css  js  c++  java
  • python collection

    一、collection系列:

    1、counter计数器

    如果counter(dict)是对字典的一个补充,如果counter(list)则是对列表的补充,初步测试对字典的值进行排序。

    ########################################################################
    ### 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


    复制代码
    ########################################################################
    ###  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
    复制代码

    实例说明:(python2.7和python3.4使用方法一样)


    import collections

    a = collections.Counter('aabadsfasfasfadfasdfsadfa')
    b = collections.Counter('1234qwrqrasfzvzvxzv')
    print(a.most_common(3))            #显示从大到小的n个数
    print(a)
    a.update(b)                                #叠加

    a.subtract(b)                              #相减


    for aa in a.elements():                 #作为迭代器,主要用于循环
    print(aa)

    a.clear()

    
    

    [('a', 9), ('f', 6), ('s', 5)]
    Counter({'a': 9, 'f': 6, 's': 5, 'd': 4, 'b': 1})


    2、有序字典(orderedDict )

    用法同dict,只是在内部维护了个列表,并对列表进行排序,即对字典的keys作了sort

    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


    复制代码
    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
    复制代码

    实例:


    >>> a = collections.OrderedDict()

    >>> a['a'] = 1
    >>> a['b'] = 2
    >>> a['c'] = 2
    >>> a
    OrderedDict([('a', 1), ('b', 2), ('c', 2)])
    >>> a['d'] = 1
    >>> a
    OrderedDict([('a', 1), ('b', 2), ('c', 2), ('d', 1)])
    >>> b = {'a':1,'b':2,'c':2,'d':1}
    >>> b
    {'a': 1, 'c': 2, 'b': 2, 'd': 1}


    3、默认字典(defaultdict) 

    即为字典中的values设置一个默认类型:

    defaultdict的参数默认是dict,也可以为list,tuple

    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


    复制代码
    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
    复制代码

    实例说明:


    在使用的dict时,无法指定values的类型,在赋值时要进行判断,具体如下:

    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]

    而在使用了defaultdict时,代码进行了简化:

    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)


    4、可命名元组(namedtuple) 

    创建一个自己的可扩展tuple的类(包含tuple所有功能以及其他功能的类型),在根据类创建对象,然后调用对象

    最长用于坐标,普通的元组类似于列表以index编号来访问,而自定义可扩展的可以类似于字典的keys进行访问

    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


    复制代码
    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
    复制代码

    实例:


     mytuple = collections.namedtuple('mytuple',['x','y','z'])

    >>> a = mytuple(5,8,3)
    >>> a
    mytuple(x=5, y=8, z=3)
    >>> a.x
    5
    >>> a.y
    8
    >>> a.z
    3
    >>> a.x * a.y /a.z
    13


    5、队列(deque)

    二种队列都是线程安全

    单项队列 是先进先出(FIFO),使用了Queue模块,其中单项和双项队列均有。

    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


    复制代码
    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
    复制代码

     实例分析:


    >>> import Queue 

    >>> dir(Queue)
    ['Empty', 'Full', 'LifoQueue', 'PriorityQueue', 'Queue', '__all__', '__builtins__', '__doc__', '__file__', '__name__', '__package__', '_threading', '_time', 'deque', 'heapq']
    >>> q = Queue.Queue(10)
    >>> q.put(1)
    >>> q
    <Queue.Queue instance at 0x7f105f87b248>
    >>> q.put(2)
    >>> q.put('a')
    >>> q.get()
    1
    >>> q.get()
    2
    >>> q.get()
    'a'
    >>> q.get()                                                         ###为空的时候阻塞,等待取最新值###

    >>> q.put(1,block=False)                                     ###指定插入不阻塞,默认是阻塞的###
    >>> q
    <Queue.Queue instance at 0x7ff590ed3098>
    >>> q.put_nowait(3)                                            ###指定插入不阻塞,默认是阻塞的###
    >>> q
    <Queue.Queue instance at 0x7ff590ed3098>
    >>> q.get()
    1
    >>> q.get(timeout=2)                                           ###指定取出阻塞,且超时2秒###
    3
    >>> q.get(timeout=2)                                           ###为空的时候抛出错误###
    Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    File "/usr/local/python279/lib/python2.7/Queue.py", line 176, in get
    raise Empty
    Queue.Empty
    >>> q.get_nowait()                                               ###为空的时候抛出错误###
    Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    File "/usr/local/python279/lib/python2.7/Queue.py", line 190, in get_nowait
    return self.get(False)
    File "/usr/local/python279/lib/python2.7/Queue.py", line 165, in get
    raise Empty
    Queue.Empty


    双向队列,被取的数据会被锁

    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


    复制代码
    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
    复制代码

     实例分析:


    >>> a = collections.deque()
    >>> a.append(1)
    >>> a.append(2)                            ###追加值到右边###
    >>> a
    deque([1, 2])
    >>> a.appendleft(3)                        ###追加值到左边###
    >>> a
    deque([3, 1, 2])
    >>> a.appendleft(3)
    >>> a.appendleft(1)
    >>> a.appendleft(2)
    >>> a
    deque([2, 1, 3, 3, 1, 2])
    >>> a.count(3)
    2
    >>> a.extend(['a','b'])                   ###将一个iterable进行遍历追加到右边###
    >>> a
    deque([2, 1, 3, 3, 1, 2, 'a', 'b'])
    >>> a.extend('abc')
    >>> a
    deque([2, 1, 3, 3, 1, 2, 'a', 'b', 'a', 'b', 'c'])
    >>> a.extendleft('abc')                    ###将一个iterable进行遍历追加到左边###
    >>> a
    >>> a
    deque(['c', 'b', 'a', 2, 1, 3, 3, 1, 2, 'a', 'b', 'a', 'b', 'c'])
    >>>

    >>> a.pop()
    'c'
    >>> a.popleft()
    'c'
    >>> a.popleft()
    'b'
    >>> a.remove(2)
    >>> a
    deque(['a', 1, 3, 3, 1, 2, 'a', 'b', 'a', 'b'])
    >>> a.remove(2)
    >>> a
    deque(['a', 1, 3, 3, 1, 'a', 'b', 'a', 'b'])
    >>> a.reverse()
    >>> a
    deque(['b', 'a', 'b', 'a', 1, 3, 3, 1, 'a'])


    二、迭代器和生成器:

    在list中有个__iter__方法,就是个迭代器,其类里必须有个next方法。需要通过遍历来具体输出

    class listiterator(object)
    | Methods defined here:
    |
    | __getattribute__(...)
    | x.__getattribute__('name') <==> x.name
    |
    | __iter__(...)
    | x.__iter__() <==> iter(x)
    |
    | __length_hint__(...)
    | Private method returning an estimate of len(list(it)).
    |
    | next(...)
    | x.next() -> the next value, or raise StopIteration

    listiterator


    复制代码
    class listiterator(object)
     |  Methods defined here:
     |  
     |  __getattribute__(...)
     |      x.__getattribute__('name') <==> x.name
     |  
     |  __iter__(...)
     |      x.__iter__() <==> iter(x)
     |  
     |  __length_hint__(...)
     |      Private method returning an estimate of len(list(it)).
     |  
     |  next(...)
     |      x.next() -> the next value, or raise StopIteration
    复制代码

    生成器内部基于yield创建,即:对于生成器只有使用时才创建,从而不避免内存浪费

    range不是生成器 和 xrange 是生成器

    readlines不是生成器 和 xreadlines 是生成器


       range(1000)

    会导致生成一个 1000 个元素的 List,而代码:

       xrange(1000)

    则不会生成一个 1000 个元素的 List,而是在每次迭代中返回下一个数值,内存空间占用很小。因为 xrange 不返回 List,而是返回一个 iterable 对象。

    带有 yield 的函数在 Python 中被称之为 generator(生成器),例:


    def kevin_readlines():
        seek = 0
        while True:
              with open('D:/eclipse/workspace/python27/first_python27/file/file.txt','r') as f:

                                             #with打开文件无需使用close来结束读取文件
                    f.seek(seek)
                    data =  f.readline()
                    if data:
                        seek = f.tell()
                        yield data
                    else:
                        return            #直接返回,退出函数

    for line in kevin_readlines():
        print(line)


    注:yeild生成器需要用循环来一行一行读取。yeild经常用于读取函数的中间值,适合用于多线程之类的情况。使用next来一次一次调用函数值。

    练习:<br>有如下列表: [132269911]

    请进行从小到大排序:
    li = [13, 22, 6, 99, 11]
    
    for m in range(len(li)-1):
        for n in range(m+1, len(li)):
            if li[m]> li[n]:
                temp = li[n]
                li[n] = li[m]
                li[m] = temp
    print(li)

    
    
     
    三、函数参数说明:

    def login(name,info,passwd = '123456')

          函数参数可以有默认值,调用函数时:

         1、如果只传二个参数,则有默认值的一定要放到最后;

    def login(name,passwd = '123456',info='welcome to you')

         2、如果传二个参数,一定要指明形参;

                 login(user)

                 login(user,passwd)

                 login(user,info='欢迎')

                 login(user,info='欢迎',passwd='123456')


    def login(*arg)        函数参数个数不定,传参数的时候可以多个,包装为列表;例:

    def list_show(*args):

        for name in args:
            print(name)
            
    list_show('a','b','c','d',1,2,3,4)        #传多个参数
    list_show(['a','b','c',1,2,3])             #直接传个列表参数


    def login(**arg)      函数参数个数不定,传参数的时候可以多个,包装为字典;例:

    def dict_show(**args):
        for name in args.items():
            print(name)      

    dict_show(name='kevin',age=23)       #传多个参数时,格式为key=value
    print('##################')

    dict = {'name':'kevin','age':23}

    dict_show(**dict)                    #直接传个字典参数时,字典前加二个**

    四、邮件函数介绍:

    具体可参考:

    python2.7版本:

    http://www.liaoxuefeng.com/wiki/001374738125095c955c1e6d8bb493182103fac9270762a000/001386832745198026a685614e7462fb57dbf733cc9f3ad000

    python3版本:

    http://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/001432005226355aadb8d4b2f3f42f6b1d6f2c5bd8d5263000

    python脚本发邮件,一般会用到smtplib和email这两个模块。看看该模块怎么使用,先看smtplib模块。

    smtplib模块定义了一个简单的SMTP客户端,可以用来在互联网上发送邮件。
    定义的类有如下:

    1
    2
    3
    class smtplib.SMTP([host[, port[, local_hostname[, timeout]]]])
    class smtplib.SMTP_SSL([host[, port[, local_hostname[, keyfile[, certfile[, timeout]]]]]])
    class smtplib.LMTP([host[, port[, local_hostname]]])

    还有一些已经定义好的异常 

    1
    2
    3
    4
    5
    6
    7
    8
    9
    exception smtplib.SMTPException
    exception smtplib.SMTPServerDisconnected
    exception smtplib.SMTPResponseException
    exception smtplib.SMTPSenderRefused
    exception smtplib.SMTPRecipientsRefused
    exception smtplib.SMTPDataError
    exception smtplib.SMTPConnectError
    exception smtplib.SMTPHeloError
    exception smtplib.SMTPAuthenticationError

    这么多已定义的类中,我们最常用的的还是smtplib.SMTP类,就具体看看该类的用法:
        smtp实例封装一个smtp连接,它支持所有的SMTP和ESMTP操作指令,如果host和port参数被定义,则smtp会在初始化期间自动调用connect()方法,如果connect()方法失败,则会触发SMTPConnectError异常,timeout参数设置了超时时间。在一般的调用过程中,应该遵connetc()、sendmail()、quit()步骤。

    下面我们来看看该类的方法:

    SMTP.set_debuglevel(level)
        设置输出debug调试信息,默认不输出调试信息。
    SMTP.docmd(cmd[, argstring])
        发送一个command到smtp服务器,
    SMTP.connect([host[, port]])
        连接到指定的smtp服务器,默认是本机的25端口。也可以写成hostname:port的形式。
    SMTP.helo([hostname])
        使用helo指令向smtp服务器确认你的身份。
    SMTP.ehlo([hostname])
        使用ehlo指令向esmtp服务器确认你的身份。
    SMTP.ehlo_or_helo_if_needed()
        如果在以前的会话连接中没有提供ehlo或者helo指令,这个方法调用ehlo()或者helo()。
    SMTP.has_extn(name)
        判断指定的名称是否在smtp服务器上。
    SMTP.verify(address)
        判断邮件地址是否在smtp服务器上存在。
    SMTP.login(user, password)
        登陆需要验证的smtp服务器,如果之前没有提供ehlo或者helo指令,则会先尝试ESMTP的ehlo指令。
    SMTP.starttls([keyfile[, certfile]])
        使smtp连接运行在TLS模式,所有的smtp指令都会被加密。
    SMTP.sendmail(from_addr, to_addrs, msg[, mail_options, rcpt_options])
        发送邮件,该方法需要一些邮件地址和消息。
    SMTP.quit()
        终止smtp会话并且关闭连接。

        经过搜索学习发现网上大多都是用smtp类的sendmail这个方法来发邮件,那就先看看这个例子:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    #!/usr/bin/python
    import smtplib
    from_mail='xxx@126.com'
    to_mail='yyy@qq.com'
    server=smtplib.SMTP('smtp.126.com')
    server.docmd('ehlo','xxx@126.com')
    server.login('xxx@126.com','password')
    msg='''from:xxx@126.com
    to:yyy@qq.com
    subject:I am guol
     
    I'm come 126
    .
    '''
    server.sendmail(from_mail,to_mail,msg)
    server.quit()

        上例是使用sendmail方式,采用邮箱验证的模式来发邮件,因为现在大多数邮件系统都有反垃圾邮件机制及验证机制,我在开始实验非验证模式时就被126当作垃圾邮件而拒绝发送。

    下面这个例子采用原始的smtp指令来发邮件。常用的smtp指令如下:

        HELO 向服务器标识用户身份
        MAIL 初始化邮件传输 mail from:
        RCPT 标识单个的邮件接收人;常在MAIL命令后面,可有多个rcpt to:
        DATA 在单个或多个RCPT命令后,表示所有的邮件接收人已标识,并初始化数据传输,以.结束
        VRFY 用于验证指定的用户/邮箱是否存在;由于安全方面的原因,服务器常禁止此命令
        EXPN 验证给定的邮箱列表是否存在,扩充邮箱列表,也常被禁用
        HELP 查询服务器支持什么命令
        NOOP 无操作,服务器应响应OK
        QUIT 结束会话
        RSET 重置会话,当前传输被取消
        MAIL FROM 指定发送者地址
        RCPT TO 指明的接收者地址

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    #!/usr/bin/python
    import base64
    import smtplib
    from_mail='xxx@126.com'
    to_mail='yyy@qq.com'
    user=base64.encodestring('xxx@126.com').strip()
    passwd=base64.encodestring('password').strip()
    server=smtplib.SMTP('smtp.126.com')
    server.set_debuglevel(1)
    server.docmd('ehlo','xxx@126.com')
    server.docmd('auth login')
    server.docmd(user)
    server.docmd(passwd)
    server.docmd('mail FROM:<%s>' % from_mail)
    server.docmd('rcpt TO:<%s>' % to_mail)
    server.docmd('data')
    server.docmd('''from:xxx@126.com
    to:yyy@qq.com
    subject:I am guol
     
    I'm come here
    .
    ''')
    server.getreply()
    server.quit()

         注意在以上两个例子中在发送消息的subject后面书写正文时,需要空一行,正文以'.'结尾。

       果然简单,如果想在邮件中携带附件、使用html书写邮件,附带图片等等,就需要使用email模块及其子模块。下面来看看email包,email包是用来管理email信息的,它包括MIME和其他基于RFC 2822的消息格式。email包的主要特征是在它内部解析和生成email信息是分开的模块来实现的。

       MIME消息由消息头和消息体两大部分组成,在邮件里就是邮件头和邮件体。邮件头与邮件体之间以空行进行分隔。

       邮件头包含了发件人、收件人、主题、时间、MIME版本、邮件内容的类型等重要信息。每条信息称为一个域,由域名后加“: ”和信息内容构成,可以是一行,较长的也可以占用多行。域的首行必须“顶头”写,即左边不能有空白字符(空格和制表符);续行则必须以空白字符打头,且第一个空白字符不是信息本身固有的。

       邮件体包含邮件的内容,它的类型由邮件头的“Content-Type”域指出。最常见的类型有text/plain(纯文本)和text/html(超文本)。邮件体被分为多个段,每个段又包含段头和段体两部分,这两部分之间也以空行分隔。常见的multipart类型有三种:multipart/mixed, multipart/related和multipart/alternative。

    在email的包里面包含了很多模块:

    email.message
    email.parser
    email.generator
    email.mime   创建email和MIME对象
    email.header
    email.charset
    email.encoders
    email.ereors
    email.utils
    email.iterators

        主要来看看email.mime,在邮件中携带附件、图片、音频时,主要使用的是该模块。一般情况下,你通过解析一个文件或者一段text来生成一个消息对象结构,你也可以从头开始建立一个消息结构,实际上,你可以给一个已经存在的消息结构追加一个新的消息对象。你可以通过创建message实例来创建一个对象结构,然后给该结构追加附件和头部信息。email包提供了一些子类使得该操作变得很容易。

    email.mime中常用的类如下:

    email.mime.base    email.mime.base.MIMEBase(_maintype, _subtype, **_params)
    email.mime.nonmultipart   email.mime.nonmultipart.MIMENonMultipart
    email.mime.multipart    email.mime.multipart.MIMEMultipart([_subtype[, boundary[, _subparts[, _params]]]])

    1
    A subclass of MIMEBase, this is an intermediate base class for MIME messages that are multipart. Optional _subtype defaults to mixed, but can be used to specify the subtype of the message. A Content-Type header of multipart/_subtype will be added to the message object. A MIME-Version header will also be added.

    email.mime.application    email.mime.application.MIMEApplication(_data[, _subtype[, _encoder[, **_params]]]) 
    email.mime.audio    email.mime.audio.MIMEAudio(_audiodata[, _subtype[, _encoder[, **_params]]]) 
    email.mime.image    email.mime.image.MIMEImage(_imagedata[, _subtype[, _encoder[, **_params]]]) 

    1
    A subclass of MIMENonMultipart, the MIMEImage class is used to create MIME message objects of major type image. _imagedata is a string containing the raw image data.

    email.mime.message    email.mime.message.MIMEMessage(_msg[, _subtype]) 
    email.mime.text    email.mime.text.MIMEText(_text[, _subtype[, _charset]]) 

    1
    A subclass of MIMENonMultipart, the MIMEText class is used to create MIME objects of major type text. _text is the string for the payload. _subtype is the minor type and defaults to plain. _charset is the character set of the text and is passed as a parameter to the MIMENonMultipart constructor; it defaults to us-ascii. If _text is unicode, it is encoded using the output_charset of _charset, otherwise it is used as-is.

    只解释了常用的几个类,详细信息见: http://docs.python.org/2/library/email.mime.html

    模拟在邮件内容中携带图片,如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    import smtplib
    from email.mime.text import MIMEText
    from email.mime.multipart import MIMEMultipart
    from email.mime.image import MIMEImage
     
    from_mail='xxx@126.com'
    to_mail='yyy@qq.com'
     
    msg=MIMEMultipart()
    msg['From']=from_mail
    msg['To']=to_mail
    msg['Subject']='I am from email package'
     
    body='I am come 126,i content with pic'
    con=MIMEText('<b>%s</b><br><img src="cid:/opt/25343674.png"><br>' % body,'html')
    msg.attach(con)
     
    img=MIMEImage(file('/opt/25343674.png','rb').read())
    img.add_header('Content-ID','/opt/25343674.png')
    msg.attach(img)
     
     
    server=smtplib.SMTP('smtp.126.com')
    server.docmd('ehlo','xxx@126.com')
    server.login('yyy@126.com','password')
    server.sendmail(from_mail,to_mail,msg.as_string())
    server.quit()

    模拟在 邮件中携带附件 ,如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    import smtplib
    from email.mime.text import MIMEText
    from email.mime.multipart import MIMEMultipart
    from email.mime.image import MIMEImage
     
    from_mail='xxx@126.com'
    to_mail='yyy@qq.com'
     
    msg=MIMEMultipart()
    msg['From']=from_mail
    msg['To']=to_mail
    msg['Subject']='I am from email package'
     
    content=MIMEText('<b>I am come 126,i with attach<b>','html')
    msg.attach(content)
     
    attac=MIMEImage(file('/opt/25343674.png','rb').read())
    attac['Content-Type']='application/octet-stream'
    attac.add_header('content-disposition','attachment',filename='/opt/25343674.png')
    msg.attach(attac)
     
     
    server=smtplib.SMTP('smtp.126.com')
    server.docmd('ehlo','xxx@126.com')
    server.login('yyy@126.com','password')
    server.sendmail(from_mail,to_mail,msg.as_string())
    server.quit()

    以上代码均在python2.7下经过测试。

    积极乐观,好好coding
  • 相关阅读:
    验证控件没有向服务器发回数据
    立即窗口中体现回车换行
    初试发布功能
    文件内码不同造成的错误
    验证控件网页代码分析3
    VB自动把变量改成小写
    maven + eclipse + tomcat 实战JSP
    Java 多线程初探(一) 创建线程
    WebSocket简单使用(一) 概念
    JDBC的事务操作
  • 原文地址:https://www.cnblogs.com/xiaodi914/p/5176177.html
Copyright © 2011-2022 走看看