生成器函数为什么执行了两次?

1 投票
2 回答
1340 浏览
提问于 2025-04-15 11:09

我在用一个Python生成器函数来获取当前目录下的图片列表。不过,我发现这个函数居然把整个列表输出了两遍,而不是一次,我也不知道为什么。我正在使用Python的PIL库来批量生成缩略图。

有没有人能给我一些建议呢?

脚本如下:


import os
import sys
import Image

class ThumbnailGenerator:
    def __init__(self, width, height, image_path, thumb_path):
        self.width = width
        self.height = height
        self.image_path = image_path
        self.thumb_path = "%s%s%s" % (self.image_path, os.sep, thumb_path)

    def __call__(self):
        self.__create_thumbnail_dir()

        for filename, image in self.__generate_image_list():
            try:
                thumbnail = "%s%s%s" % (self.thumb_path, os.sep, filename)
                image.thumbnail((self.width, self.height))
                image.save(thumbnail, 'JPEG')
                print "Thumbnail gemaakt voor: %s" % filename
            except IOError:
                print "Fout: thumbnail kon niet gemaakt worden voor: %s" % filename

    def __generate_image_list(self):
        for dirpath, dirnames, filenames in os.walk(self.image_path):
            count = 0
            for filename in filenames:
                try:
                    image = Image.open(filename)
                    print '=========', count, filename
                    count += 1
                    yield (filename, image)
                except IOError:
                    pass

    def __create_thumbnail_dir(self):
        try:
            os.mkdir(self.thumb_path)
        except OSError as exception:
            print "Fout: %s" % exception

if __name__ == '__main__':
    try:
        thumbnail_generator = ThumbnailGenerator(80, 80, '.', 'thumbs')
        thumbnail_generator()
    except KeyboardInterrupt:
        print 'Programma gestopt'

目前这个脚本的输出(测试用的图片)是:

========= 0 124415main_image_feature_380a_ys_full.jpg
Thumbnail gemaakt voor: 124415main_image_feature_380a_ys_full.jpg
========= 1 60130main_image_feature_182_jwfull.jpg
Thumbnail gemaakt voor: 60130main_image_feature_182_jwfull.jpg
========= 2 assetImage.jpg
Thumbnail gemaakt voor: assetImage.jpg
========= 3 devcon-c1-image.gif
Fout: thumbnail kon niet gemaakt worden voor: devcon-c1-image.gif
========= 4 image-646313.jpg
Thumbnail gemaakt voor: image-646313.jpg
========= 5 Image-Schloss_Nymphenburg_Munich_CC.jpg
Thumbnail gemaakt voor: Image-Schloss_Nymphenburg_Munich_CC.jpg
========= 6 image1w.jpg
Thumbnail gemaakt voor: image1w.jpg
========= 7 New%20Image.jpg
Thumbnail gemaakt voor: New%20Image.jpg
========= 8 samsung-gx20-image.jpg
Thumbnail gemaakt voor: samsung-gx20-image.jpg
========= 9 samsung-image.jpg
Thumbnail gemaakt voor: samsung-image.jpg
========= 0 124415main_image_feature_380a_ys_full.jpg
Thumbnail gemaakt voor: 124415main_image_feature_380a_ys_full.jpg
========= 1 60130main_image_feature_182_jwfull.jpg
Thumbnail gemaakt voor: 60130main_image_feature_182_jwfull.jpg
========= 2 assetImage.jpg
Thumbnail gemaakt voor: assetImage.jpg
========= 3 devcon-c1-image.gif
Fout: thumbnail kon niet gemaakt worden voor: devcon-c1-image.gif
========= 4 image-646313.jpg
Thumbnail gemaakt voor: image-646313.jpg
========= 5 Image-Schloss_Nymphenburg_Munich_CC.jpg
Thumbnail gemaakt voor: Image-Schloss_Nymphenburg_Munich_CC.jpg
========= 6 image1w.jpg
Thumbnail gemaakt voor: image1w.jpg
========= 7 New%20Image.jpg
Thumbnail gemaakt voor: New%20Image.jpg
========= 8 samsung-gx20-image.jpg
Thumbnail gemaakt voor: samsung-gx20-image.jpg
========= 9 samsung-image.jpg
Thumbnail gemaakt voor: samsung-image.jpg

而它应该是:

========= 0 124415main_image_feature_380a_ys_full.jpg
Thumbnail gemaakt voor: 124415main_image_feature_380a_ys_full.jpg
========= 1 60130main_image_feature_182_jwfull.jpg
Thumbnail gemaakt voor: 60130main_image_feature_182_jwfull.jpg
========= 2 assetImage.jpg
Thumbnail gemaakt voor: assetImage.jpg
========= 3 devcon-c1-image.gif
Fout: thumbnail kon niet gemaakt worden voor: devcon-c1-image.gif
========= 4 image-646313.jpg
Thumbnail gemaakt voor: image-646313.jpg
========= 5 Image-Schloss_Nymphenburg_Munich_CC.jpg
Thumbnail gemaakt voor: Image-Schloss_Nymphenburg_Munich_CC.jpg
========= 6 image1w.jpg
Thumbnail gemaakt voor: image1w.jpg
========= 7 New%20Image.jpg
Thumbnail gemaakt voor: New%20Image.jpg
========= 8 samsung-gx20-image.jpg
Thumbnail gemaakt voor: samsung-gx20-image.jpg
========= 9 samsung-image.jpg
Thumbnail gemaakt voor: samsung-image.jpg

如你所见,这个生成器函数返回了两次列表(我确认它只被调用了一次)。

@heikogerlach: os.walk找不到缩略图,因为我是在遍历当前目录的文件名,而缩略图是写入当前目录下一个叫“thumb”的子文件夹里的。列表是在把缩略图写入“thumb”目录之前生成的,我用WinPDB确认过,缩略图并没有包含在列表里。

@S.Lott: 谢谢你的建议。os.path.join解决了这个问题。

2 个回答

0

你的缩略图存放在self.image_path的一个子文件夹里,并且它们的名字和原始图片是一样的。你能检查一下在你创建缩略图的时候,walk是否能找到这些缩略图吗?只需要打印出图片的路径和名字就可以了。

3

在调试的时候,打印出完整的路径。我觉得你是在访问完.目录后,又进入了thumbs子目录。

还有。

class ThumbnailGenerator( object ):

从长远来看,这样通常会更好。

请不要在你的方法名字前面加__(比如generate_image_list和create_thumbnail_dir)。

不要用"%s%s%s" % (self.image_path, os.sep, thumb_path)来拼接路径,应该使用os.path.join

撰写回答