• yield关键字的使用


    先来段最简单的代码:

    def  iter():
    for i in range(10):
    yield i

    调用这个方法:

    >>>check_iter = iter()
    >>>dir(check_iter)
    [
    '__class__', '__delattr__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__iter__', '__name__', '__new__', '__reduce__', '__
    reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'close', 'gi_code', 'gi_frame', 'gi_running', 'next', 'send', 'throw']
    可以看到有一个next属性,调用之
    >>> check_iter.next()
    0
    >>> check_iter.next()
    1
    >>> check_iter.next()
    2
    >>> check_iter.next()
    会发现check_iter通过next()会逐渐的返回原来iter函数的值,而不是像return 那样直接返回一个list给调用处,那么这里有人就定义yield这里的作用是生成器了!

    深度研究,以python中自带的UserDict模块下的DictMixin作为研究对象,研究yield关键字的用法

    class DictMixin:
    # Mixin defining all dictionary methods for classes that already have
    # a minimum dictionary interface including getitem, setitem, delitem,
    # and keys. Without knowledge of the subclass constructor, the mixin
    # does not define __init__() or copy(). In addition to the four base
    # methods, progressively more efficiency comes with defining
    # __contains__(), __iter__(), and iteritems().

    # second level definitions support higher levels
    def __iter__(self):
    for k in self.keys():
    yield k
    def has_key(self, key):
    try:
    value
    = self[key]
    except KeyError:
    return False
    return True
    def __contains__(self, key):
    return self.has_key(key)

    # third level takes advantage of second level definitions
    def iteritems(self):
    for k in self:
    yield (k, self[k])
    def iterkeys(self):
    return self.__iter__()

    # fourth level uses definitions from lower levels
    def itervalues(self):
    for _, v in self.iteritems():
    yield v
    def values(self):
    return [v for _, v in self.iteritems()]
    def items(self):
    return list(self.iteritems())
    def clear(self):
    for key in self.keys():
    del self[key]
    def setdefault(self, key, default=None):
    try:
    return self[key]
    except KeyError:
    self[key]
    = default
    return default
    def pop(self, key, *args):
    if len(args) > 1:
    raise TypeError, "pop expected at most 2 arguments, got "\
    + repr(1 + len(args))
    try:
    value
    = self[key]
    except KeyError:
    if args:
    return args[0]
    raise
    del self[key]
    return value
    def popitem(self):
    try:
    k, v
    = self.iteritems().next()
    except StopIteration:
    raise KeyError, 'container is empty'
    del self[k]
    return (k, v)
    def update(self, other=None, **kwargs):
    # Make progressively weaker assumptions about "other"
    if other is None:
    pass
    elif hasattr(other, 'iteritems'): # iteritems saves memory and lookups
    for k, v in other.iteritems():
    self[k]
    = v
    elif hasattr(other, 'keys'):
    for k in other.keys():
    self[k]
    = other[k]
    else:
    for k, v in other:
    self[k]
    = v
    if kwargs:
    self.update(kwargs)
    def get(self, key, default=None):
    try:
    return self[key]
    except KeyError:
    return default
    def __repr__(self):
    return repr(dict(self.iteritems()))
    def __cmp__(self, other):
    if other is None:
    return 1
    if isinstance(other, DictMixin):
    other
    = dict(other.iteritems())
    return cmp(dict(self.iteritems()), other)
    def __len__(self):
    return len(self.keys())

     关于此类,大家可以从注释中看到“Mixin类定义了所有的字典方法,前提是要有一个字典接口,包括getitem,setitem,delitem,和key”,揣测下要有key值,即必须是{"key" : "value"}这种类型,必须有一个元素,如果不对,欢迎拍砖。因为学习的过程就是体会错误的过程。我们看到有一个__iter__内置方法有yield关键字.也就是说这里是一个生产器,在其他地方,也就是调用处调用这个方法的时候,会使用到与之相关的next()方法

    >>> a = {'hello' : 'world'}
    >>> a = {'hello' : 'world', '你好' : '世界'}
    >>> id(a.iterkeys())
    11284272
    >>> id(a.iterkeys())
    11284224
    >>> id(a.iterkeys())
    11284272
    >>> id(a.iterkeys())
    11284224
    你可以看到这里是通过调用iterkeys()方法,然后掉用内置方法__iter__,获得的key值的内存地址,如果你仍然纠结并没有显式看到next方法,那么,别急,在看这个源码的其他地方:

      在iteritems方法中有一个yield关键字:

    def iteritems(self):
    for k in self:
    yield (k, self[k])

      

     偶调用他的地方是:

    def popitem(self):
    try:
    k, v
    = self.iteritems().next()
    except StopIteration:
    raise KeyError, 'container is empty'
    del self[k]
    return (k, v)

     iteritems方法返回一个tuple类型的值,请你清楚,tuple是以","作为标志的,而不是"()",所以 python会有return a,b这种return语句出现的,而实际上在很多计算机语言是不允许返回多个值的。其实python也一样!那么这里通过 yield返回了一个tuple,即key和value对应的tuple,而现在想得到下一个,next()就在这里出现了。

  • 相关阅读:
    spring boot启动原理
    Minor GC ,Full GC 触发条件是什么?
    Redis分布式锁的正确实现方式Jedis客户端实现方式总结
    JVM命令总结
    InnoDB中B+树总结
    ThreadPoolExecutor 优先级的线程池
    锁的概述
    Deadlock Troubleshooting, Part 1
    Deadlock Troubleshooting, Part 3
    大型网站数据库优化和故障跟踪与排查(下篇)
  • 原文地址:https://www.cnblogs.com/CLTANG/p/2141565.html
Copyright © 2020-2023  润新知