批量使用Python将文件名附加到目录中

时间:2023-02-06 10:41:56

I've just started with Python and this is my first 'own' program. I've explained (to the best of my ability) what I intend my program to achieve. Since I'm new, I'd appreciate any syntax/performance improvement suggestions you may have.

我刚刚开始使用Python,这是我的第一个“自己的”程序。我已经(尽我所能)解释了我打算实现的计划。由于我是新手,因此我非常感谢您提供的任何语法/性能改进建议。

   '''
        Search through a target movies directory and filter movie titles
        to search IMDb for movie ratings. After fetching, append ratings
        to corresponding movie files/folders in the directory.

        File names are in one of the following formats:
        1. P.S. I Love You.mkv
        2. P.S. I Love You (2010).mp4
        3. P.S. I Love You (2010) [1080p].avi

        Ideally, this program fetched the movie ratings and adds it to
        the end of the file name (just before the extension). The query,
        in this case, would be http://www.omdbapi.com/?t=P.S.+I+Love+You

        Ideally, the file in the directory would be renamed to one of the
        following:
        1. P.S. I Love You (7.1).mkv
        2. P.S. I Love You (2010) (7.1).mp4
        3. P.S. I Love You (2010) [1080p] (7.1).avi
    '''

    import os, json, urllib.request, re

    # Query related constants
    base_uri = "http://www.omdbapi.com/?"
    query_title = "t="

    basepath = "E:/Movies"

    # Fetch movie rating from omdbapi.com
    # Example JSON response: http://www.omdbapi.com/?t=insurgent
    def getRating(movie_title):
        # json_response = urllib.urlopen(base_uri + query_title + movie_title)
        # movie_data = json.loads(json_response.read())
        with urllib.request.urlopen(base_uri + query_title + movie_title) as url:
            movie_data = url.read()
        return movie_data['imdbRating']

    # Checks if parameter file name already has a rating.
    # Movie ratings are
    def hasRating(filename):
        pattern = re.compile('\([0-9].[0-9]\)')
        if pattern.search(filename) is not None:
            return True
        return False

    # Get the movie title by stripping out excess information such as the
    # year released or video definition
    def getMovieTitle(filename):
        if '(' not in filename is False:
            return filename.split('(')[0]
        elif'[' not in filename is False:
            return filename.split('[')[0]
        return os.path.splitext(basepath + filename)[:-1]


    def main():
        for file in os.listdir(basepath):
            if hasRating(file) is False:
                movie_title = getMovieTitle(file)
                file_ext = os.path.splitext(basepath + file)[-1:]
                movie_rating = getRating(movie_title)
                formatted_rating = ' (' + movie_rating + ')'
                file_no_ext = os.path.splitext(basepath + file)[:-1]

                os.rename(file, file_no_ext + ' ' + formatted_rating + file_ext)

    if __name__ == '__main__':
        main()

I've tried to fix everything I can so far but I keep arriving at the same error:

到目前为止,我已尝试修复所有内容,但我仍然遇到同样的错误:

Traceback (most recent call last):
  File "renamer.py", line 65, in <module>
    main()
  File "renamer.py", line 58, in main
    movie_rating = getRating(movie_title)
  File "renamer.py", line 33, in getRating
    with urllib.request.urlopen(base_uri + query_title + movie_title) as url:
TypeError: Can't convert 'tuple' object to str implicitly

Please let me know what a TypeError is, why it occurs, and what I can do to fix it.

请让我知道TypeError是什么,它为什么会发生,以及我可以做些什么来解决它。

Coming from Java, the simplicity of Python is kind of overwhelming but refreshing at the same time. Anyway, thanks in advance for your input!

来自Java,Python的简单性是压倒性的,但同时又令人耳目一新。无论如何,提前感谢您的意见!

1 个解决方案

#1


2  

In your case getMovieTitle returns a tuple if no if condition is true. So movie_title is a tuple and getRating can't handle that ("adding" of strings and tuples results in a TypeError exception).

在你的情况下,如果条件为真,则getMovieTitle返回一个元组。所以movie_title是一个元组,而getRating无法处理它(“添加”字符串和元组会导致TypeError异常)。

Returning the last element of a list is done by [-1]. What you expect to use from os.path.splitext is the first part, so use index 0.

返回列表的最后一个元素是由[-1]完成的。您期望从os.path.splitext使用的是第一部分,因此请使用索引0。

return os.path.splitext(basepath + filename)[:-1]

turn this line to

将此行转为

return os.path.splitext(basepath + filename)[0]

Second, you're accessing movie_data which is a string after reading with url.read() by movie_data['imdbRating']. What you most probably want is to decode the result (which is json) and then access the element:

其次,您正在通过movie_data ['imdbRating']读取url.read()后访问movie_data,这是一个字符串。你最想要的是解码结果(这是json),然后访问元素:

with urllib.request.urlopen(base_uri + query_title + movie_title) as url:
    movie_data = json.loads(url.read())['imdbRating']

This works as long 'imdbRating' is a key in the root dictionary.

这有效,因为'imdbRating'是根字典中的一个关键字。

#1


2  

In your case getMovieTitle returns a tuple if no if condition is true. So movie_title is a tuple and getRating can't handle that ("adding" of strings and tuples results in a TypeError exception).

在你的情况下,如果条件为真,则getMovieTitle返回一个元组。所以movie_title是一个元组,而getRating无法处理它(“添加”字符串和元组会导致TypeError异常)。

Returning the last element of a list is done by [-1]. What you expect to use from os.path.splitext is the first part, so use index 0.

返回列表的最后一个元素是由[-1]完成的。您期望从os.path.splitext使用的是第一部分,因此请使用索引0。

return os.path.splitext(basepath + filename)[:-1]

turn this line to

将此行转为

return os.path.splitext(basepath + filename)[0]

Second, you're accessing movie_data which is a string after reading with url.read() by movie_data['imdbRating']. What you most probably want is to decode the result (which is json) and then access the element:

其次,您正在通过movie_data ['imdbRating']读取url.read()后访问movie_data,这是一个字符串。你最想要的是解码结果(这是json),然后访问元素:

with urllib.request.urlopen(base_uri + query_title + movie_title) as url:
    movie_data = json.loads(url.read())['imdbRating']

This works as long 'imdbRating' is a key in the root dictionary.

这有效,因为'imdbRating'是根字典中的一个关键字。