为什么这段代码无限循环?

时间:2012-07-14 18:14:35

标签: python infinite-loop

我正在为体验和知识编写搜索引擎。现在,我正在构建一个爬虫及其附带的实用程序。其中之一是URL规范化程序。这就是我现在正在努力构建的内容,更具体地说,我不得不采用一种方法来获取网址,并将字母大写为“%”符号。到目前为止我的代码:

def escape_sequence_capitalization(url):
        ''' The method that capitalizes letters in escape sequences.
        All letters within a percent - encoding triplet (e.g. '%2C') are case
        insensitive and should be capitalized.

        '''
    next_encounter = None
    url_list = []
    while True:
        next_encounter = url.find('%')
        if next_encounter == -1:
            break

        for letter in url[:next_encounter]:
            url_list.append(letter)

        new_character = url[next_encounter + 1].upper()
        url_list.append(new_character)
        url = url[next_encounter:]

    for letter in url:
        url_list.append(letter)

    return ''.join(url_list)

有人可以指导我到我错误的地方吗?我会很感激。谢谢。

编辑:这就是我想要实现的目标:

http://www.example.com/a%c2%b1b → http://www.example.com/a%C2%B1b

4 个答案:

答案 0 :(得分:10)

通过静态分析,它会永远循环,因为while True永远不会中断。那么哪里可以打破?仅当break变为等于-1时才在next_encounter语句处;所以你可以推断它从来没有。

为什么不呢?在print next_encounter后尝试url.find。你很快就会看到

url = url[next_encounter:]

几乎可以实现你所希望的,只有它给你一个比你希望的更多的角色。

为什么我这样呈现呢?主要是因为print的价值经常被学习语言的人低估。

答案 1 :(得分:4)

@msw钉了它并给出了合理的建议。

我的$ .02是你从来没有尝试过这个循环

怎么样:

>>> re.sub('%..',lambda m: m.group(0).upper(),'http://www.example.com/a%c2%b1b')
'http://www.example.com/a%C2%B1b'

答案 2 :(得分:3)

这就是原因:

>>> 'asd'.find('s')
1
>>> 'asd'[1:]
'sd'

另外,请考虑使用str.find()的第二个参数而不是切片。

答案 3 :(得分:1)

我来参加派对有点晚了,但你可能想考虑使用正则表达而不是这么复杂的功能:

>>> import re
>>> url = "http://www.example.com/a%c2%b1b"
>>> result = re.sub("(?i)%[0-9A-F]{2}", lambda x: x.group(0).upper(), url)
>>> result
'http://www.example.com/a%C2%B1b'

<强>解释

(?i)          # Make regex case-insensitive
%             # Match a %
[0-9A-F]{2}   # Match two hex digits

re.sub()在字符串中查找所有这些事件,并将结果(匹配对象的group(0))传递给.upper()方法,然后将原始版本替换为匹配的大写版本。