Python 3.2.2 函数在非空变量上返回 None

2 投票
2 回答
1534 浏览
提问于 2025-04-17 05:15

我正在写一个简单的脚本,用来下载一系列TED演讲的视频,前提是我有这些TED演讲网站链接的列表:

# Run through a list of TEDTalk website links and download each
# TEDTalk in high quality MP4

import urllib.request

#List of website links
l = [
        "http://www.ted.com/index.php/talks/view/id/28",
        "http://www.ted.com/index.php/talks/view/id/29",
    ]

# Function which takes the location of the string "-480p.mp4",
# d = 1 less that location, and a string and returns the
# full movie download link
def findFullURL(d, e, s):
    a = s[d]
    if a != "/":
        #Subtract from d to move back another letter
        d = d - 1
        findFullURL(d, e, s)
    else:
        fullURL = "http://download.ted.com/talks/" + s[(d+1):e] + "-480p.mp4"
        #print(fullURL)
        return fullURL

#Iterate through a list of links to download each movie
def iterateList(l):
    for x in l:
        #get the HTML
        f = urllib.request.urlopen(x)
        #Convert the HTML file into a string
        s = str(f.read(), "utf-8")
        f.close()
        #Find the location in the string where the interesting bit ends
        e = s.find("-480p.mp4")
        d = e - 1
        #The problem is with this variable url:
        url = findFullURL(d, e, s)
        print("Downloading " + url)
        #TODO: Download the file

我很确定函数findFullURL是有效的。如果你在findFullURL函数的最后取消注释print(fullURL)这一行,你会看到它输出的下载链接正是我需要的。

但是,在iterateList函数中,当我试图通过url = findFullURL(d, e, s)来获取这个字符串时,变量url似乎变成了None。我对此完全不理解。它应该和下面这个例子一样简单,而这个例子在我尝试时是可以正常工作的:

def hello():
    return "Hello"
url = hello()
print(url)

2 个回答

2

findFullURL这个函数在第一个条件判断的分支里没有写return语句。这在Python里意味着它会返回None,也就是什么都不返回。

10

我确信这个函数 findFullURL 是有效的。

确信某段代码有效,往往是浪费几个小时调试时间的最佳方式,因为你可能在错误的地方寻找问题。

实际上,这个函数并不好用。你缺少一个返回值:

def findFullURL(d, e, s):
    a = s[d]
    if a != "/":
        #Subtract from d to move back another letter
        d = d - 1
        return findFullURL(d, e, s)   # <<<<<<< here
    else:
        fullURL = "http://download.ted.com/talks/" + s[(d+1):e] + "-480p.mp4"
        #print(fullURL)
        return fullURL

另外,你不应该用递归来解决这个问题。你可以用 rfind 来代替。

def findFullURL(d, e, s):
    d = s.rfind('/', 0, d + 1)
    # You probably want to handle the condition where '/' is not found here.
    return "http://download.ted.com/talks/" + s[(d+1):e] + "-480p.mp4"

撰写回答