【问题标题】:Python - null object pattern with generatorsPython - 带有生成器的空对象模式
【发布时间】:2015-05-20 04:35:57
【问题描述】:

返回可以被视为成功返回类型的“假”版本的值显然是 Pythonic,因此if MyIterableObject: do_things() 是一种处理输出的简单方法,无论它是否实际存在。

对于生成器,bool(MyGenerator) 始终为 True,即使它的 len 为 0 或同样为空。所以虽然我可以写如下内容:

result = list(get_generator(*my_variables))
if result:
    do_stuff(result)

似乎它首先破坏了拥有生成器的好处。

也许我只是缺少一个语言功能或其他东西,但是 pythonic 语言结构是什么,用于明确指示不能使用空生成器完成工作?

为了清楚起见,我希望能够让用户了解脚本实际做了多少工作(如果有的话) - 上下文 sn-p 如下:

# Python 2.7
templates = files_from_folder(path_to_folder)
result = list(get_same_sections(templates)) # returns generator
if not result:
    msg("No data to sync.")
    sys.exit()

for data in result:
    for i, tpl in zip(data, templates):
        tpl['sections'][i]['uuid'] = data[-1]

msg("{} sections found to sync up.".format(len(result)))

它有效,但我认为最终将生成器更改为列表只是为了看看是否有任何工作要做,所以我认为有更好的方法,是吗?

编辑:我觉得生成器不应该以这种方式使用,但我将添加一个示例来说明我的推理。

当您需要遍历诸如嵌套dict 或what-have-you 之类的结构时,您会时不时地看到Python 中有一个半流行的“辅助函数”。通常称为getnodegetn,每当我看到它时,它都会读到这样的内容:

def get_node(seq, path):
    for p in path:
        if p in seq:
            seq = seq[p]
        else:
            return ()
    return seq

因此,通过这种方式,您可以更轻松地处理嵌套结构中数据的复杂路径的结果,而无需在您实际上并未处理“异常情况”时始终检查 Nonetry/except '。

mydata = get_node(my_container, ('path', 2, 'some', 'data'))
if mydata:  # could also be "for x in mydata", etc
    do_work(mydata)
else:
    something_else()

它看起来不太像这种语法将(或可能)存在于生成器中,而不像建议的那样编写一个以这种方式处理生成器的类。

【问题讨论】:

标签: python-2.7 generator


【解决方案1】:

在您用尽迭代之前,生成器没有长度。

唯一能判断它是否有任何东西的方法就是用尽它

items = list(myGenerator)

if items:
    # do something

除非您编写了一个具有 nonzero 属性的类,该类在内部查看您的迭代列表

class MyGenerator(object):

    def __init__(self, items):
        self.items = items

    def __iter__(self):
        for i in self.items:
            yield i

    def __nonzero__(self):
        return bool(self.items)

>>> bool(MyGenerator([]))
False
>>> bool(MyGenerator([1]))
True
>>> 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-07-13
    • 2012-01-25
    • 2012-09-10
    • 2015-07-26
    • 2010-10-31
    • 2013-01-05
    • 1970-01-01
    相关资源
    最近更新 更多