抑制字符串的迭代处理

问题描述

不幸的是,没有任何方法可以自动执行此操作。您提出的解决方案(str不可迭代的子类)遭受与isinstance()…相同的问题,即,您必须记住在使用字符串的任何地方都使用它,因为无法使Python代替它来使用它。本机类。当然,您不能用猴子修补内置对象。

我可能建议,如果您发现自己编写的函数使用可迭代的容器 字符串,则可能是您的设计有问题。但是有时您无法避免。

在我看来,最不麻烦的事情是将检查放入函数中,并在进入循环时调用函数。至少这会将行为更改放在您最有可能看到的位置:在for语句中,不要埋藏在班级的某个地方。

def iterate_no_strings(item):
    if issubclass(item, str):   # issubclass(item, basestring) for Py 2.x
        return iter([item])
    else:
        return iter(item)

for thing in iterate_no_strings(things):
    # do something...

解决方法

更新:

在2006年python.org上提出了使内置字符串不可迭代的想法。我的问题有所不同,因为我试图偶尔仅抑制一次此功能。整个线程还是很相关的。

这是Guido的批判性评论,他们str在试用的基础上实施了不可重复的操作:

[…]我实现了这一点(这确实很简单),但是后来发现我不得不修复大量遍历字符串的地方。例如:

  • sre解析器和编译器使用set(“ 0123456789”)之类的东西,并且还对输入正则表达式的字符进行迭代以对其进行解析。

* difflib具有为两个字符串列表(一个文件的典型逐行差异),两个字符串(一个典型的行内差异)或什至两个东西的列表(对于通用序列差异)定义的API 。

  • optparse.py,textwrap.py,string.py中的小变化。

而且我什至不在regrtest.py框架可以工作的地方(由于difflib问题)。

我正在放弃这个项目;该补丁是SF补丁1471291。我不再支持这个想法。这只是不切实际的,并且我在sre和difflib中都发现了用例,驳斥了没有充分理由遍历字符串的前提。

原始问题:

尽管字符串的可重复性是该语言的一项巧妙功能,但与鸭子输入结合使用时,可能会导致灾难:

# record has to support [] operation to set/retrieve values
# fields has to be an iterable that contains the fields to be set
def set_fields(record,fields,value):
  for f in fields:
    record[f] = value

set_fields(weapon1,('Name','ShortName'),'Dagger')
set_fields(weapon2,),'Katana')
set_fields(weapon3,'Name','Wand') # I was tired and forgot to put parentheses

不会引发异常,除非通过isinstance(fields,str)在众多地方进行测试,否则没有简单的方法来捕获此异常。在某些情况下,此错误将需要很长时间才能找到。

我想在我的项目中完全禁止将字符串视为可迭代对象。这是个好主意吗?是否可以轻松,安全地完成?

也许我可以对内置对象进行子类化,str以便在get_iter()希望将其对象视为可迭代对象时需要显式调用。然后,每当我需要字符串文字时,我都将创建此类的对象。

以下是一些与切线相关的问题:

如何判断python变量是字符串还是列表?