拟议的新PEP:打印以扩展发电机

我想为Python提供拟议的增强. 我描述了 下面的基本思想,以表达社区的利益. 现在,只是 一个主意,我敢肯定还有改进的空间. 当然是 我可能会忽略一些严重的"陷阱". 因此,我欢迎任何 和所有评论. 如果达成协议,该提议值得进一步考虑 然后,我将以官方PEP格式重新提交正式文档. 问候 -JB PEP-扩展打印以扩展发电机 简而言之 我建议我们扩展"打印"的语义,以便如果对象 被打印是发电机,然后打印将迭代在结果上 亚物体的顺序和递归按顺序打印每个项目. 例如., 打印OBJ 根据该提议的行为会像 导入类型 如果type(obj)== type.generatortype: 对于OBJ中的项目: 打印项目,#递归电话 打印#Tailing Newline 别的: 打印OBJ#现有印刷行为 我知道这不是恰恰是打印的工作方式,但我有意 简化了插图,以强调预期的变化. 尽管如此, 上面的几点明确是该提案的一部分(请 讨论和可能的修订): 除了情况外,印刷行为不会改变 要打印的对象是生成器. 枚举物品用中间空间打印 [或者:""或" \ n"]. 列举的序列以新线结束 [或者:""或""]. 迭代器本身可以将迭代器作为元素返回,并提议 打印的更改将递归地序列化迭代器的任何任意"树". 对于复杂的用户定义对象,__str __()然后可以返回迭代器,并且 任意复杂的结构可以打印出来而无需打印 一切都变成了一个巨大的字符串 - 最终将其扔掉. 我希望我们也可能想修改str()本身来体现这个 序列化行为. 这种额外的更改将支持这些情况 实际上,最终确实想要一个大字符串的地方,例如 存储到UI小部件中. 尽管如此,该字符串仍将在 结局,比建造一堆较小的中级要高得多 字符串. 然后,从抽象的意义上说,我们根本不会改变打印 - 新的 语义将体现在变为str()的更改中. 但是,实际上, 我们还希望修改打印,作为更多的重要优化 常见用例. 当前的行为(例如,显示" ") 仍然可以通过 打印reter(发电机) 请注意,此行为目前是由所有三个: 打印生成器 打印str(发电机) 打印reter(发电机) 因此,该提议仅将有用的新语义归因于 三个冗余语言结构. 动机 随着越来越复杂的对象,打印表示自然变为 更复杂. 特别是,当一个物体由 集合 子对象,定义其字符串表示很自然 根据子组件的字符串表示形式递归 进一步指出他们如何团结在一起. 这可以使用__str__超载和现有打印 语义. 但是,现有的语义需要构建许多否则 不必要的中间字符串,因此非常低效. 更糟糕的是,每个中间字符串通常是几个 以前的中介机构,因此中间结果的体积稳定 在整个转换过程中增加. 最后,字符串操作的成本 与有关弦的长度成正比,所以我希望 总体成本的增加速度明显比直接成比例的 输出的大小(即非线性). 例如,以下课程的实例可能会变得任意昂贵 打印出: def htmltable(对象): #... def __str __(self): 返回(" \ n" +"" .join([self.head]行的[str(row)]) +"" .join([self in self.Rows in self.Rows in self.Rows]) +" \ n") def htmlrow(对象): #... def __str __(self): 返回(" \ n" +"" .join(self.cells中的单元格的str(str(细胞)))) +" \ n") def htmlcell(对象): #... def __str __(self): 返回(" \ n" +"" .join(self.data中基准的[str(datum)]) +" \ n") 显然,打印任意的htmltable可能需要很多不必要的 字符串操纵. 使用建议的扩展程序,可以实现上述示例 就像: def htmltable(对象): #... def __str __(self): 产量" <表" 产量str(self.attr) 屈服"> \ n" 对于self.head中的行: 产量str(行) 对于自self.行:行: 产量str(行) 产量" \ n" def htmlrow(对象): #... def __str __(self): 产量" \ n" 用于self.cells中的细胞: 产生str(细胞) 产量" \ n" def htmlcell(对象): #... def __str __(self): 产量" \ n" 对于self.data中的基准: 产量str(datum) 产量" \ n" 有了新的扩展,单个数据位简单地输出 正确的订单,实际上消除了不必要的字符串操作,由此产生 巨大的性能改进. 实际上,在常见的情况下 叶节点是字面字符串,然后是整个HTML表(或页面!) 可以在没有任何字符串操作的情况下写出 - 现有字符串 简单地从他们现在的记忆中写出! 此外,在 建议的新方法. 该提议背后的主要动机是消除不必要的 开销,同时保留现有语义的所有便利性 自定义对象的字符串表示. 虽然它不是100%向后兼容,但它为其中一个分配了新的含义 几个冗余 现有的语言结构. 备择方案 用户可以定义自己的辅助功能,代替拟议的更改 生成输出. 例如.: def htmltable(对象): #... def pr(self,stream = sys.stdout): " >流,str(self.attr) 打印>>流,"> \ n" 对于self.head中的行: 打印>>流,行 自self.行: 打印>>流,行 打印>>流," " 我本人已经成功地在各种应用程序中使用了这种技术. Pro: 不需要更改Python 骗局: 在每种情况下必须"手工制作"解决方案, 受用户错误的约束. 该解决方案仅在用户明确维护 整个班级等级的惯例. 该解决方案不可与对象互换 来自其他作者. ///

# 回答1

在文章, " James J. Besemer" 写道: 我相信您想要的功能已经存在,或者非常 靠近它,在Pprint(漂亮的打印机)模块中.
# 回答2

詹姆斯·J·贝塞默(James J. Besemer)写道: 我不想正确地搜索特定的python-dev线程 现在,但是以前提出过这样的事情(我认为 "%i"格式代码),Guido强烈认为加法或 删除简单的打印语句不应改变 周围代码. 考虑诸如::的代码 项目= get_generator_or_none() 对于项目中的项目: do_something(项目) 现在,假设我插入了一个像::的调试线 项目= get_generator_or_none() 打印"确保这不是没有:",项目 对于项目中的项目: do_something(项目) 现在,我的调试线刚刚打破了我的剩余代码. 这不好. 我认为这种PEP不应该前进的另一个原因(至少为 是)是Python 3000已经将打印说明转动 进入功能(尽管该功能的确切细节尚未 哈希还出去). 因此,在打印语句中添加额外的crufft是友好的 浪费的努力. 史蒂夫
# 回答3

詹姆斯·J·贝塞默(James J. Besemer) 请不要: 从Itertools进口周期 def mygen(): 返回周期('这是一个非常糟糕的想法'.split())

标签: python

添加新评论