TypeError: NoneType - 使用时返回 zip_longest [英] TypeError: NoneType - When using return zip_longest

查看:72
本文介绍了TypeError: NoneType - 使用时返回 zip_longest的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

目前我收到 NoneType 的类型错误(我假设当我尝试在函数中为 zip_longest 返回一个值时)

I am getting a type error for NoneType at the moment this is (I assume when I am trying to return a value in a function for zip_longest)

我的代码的目的是删除小于宽度 = 400 AND 高度 = 400"的图像文件,然后将所有剩余的图像放入 x 值的文件夹中(其中 x 可以稍后更改).目前代码似乎可以工作,但我遇到了我提到的问题,并希望防止该错误.

The objective of my code is to remove image files that are smaller the "width = 400 AND height = 400" and then placing all remaining images into folders of x value (where x can be changed later on). Currently the code seems to work but I get the issue I mentioned and would like to prevent that error.

代码:

# ======== grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx:
def grouper(iterable, n, fillvalue=None):
    "Collect data into fixed-length chunks or blocks"
    # grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx"
    args = [iter(iterable)] * n
    print(fillvalue)
    return zip_longest(*args, fillvalue=fillvalue)


def makedirs(d):
    try:
        os.makedirs(d)
    except OSError as e:
        # If the file already exists, and is a directory
        if e.errno == errno.EEXIST and os.path.isdir(d):
            created = False
        # It's some other error, or the existing file is not a directory
        else:
            raise
    else:
        created = True

    return created


def get_valid_filenames(directory, extensions):
    for filename in os.listdir(directory):
        if filename.lower().endswith(extensions):
            yield filename


def get_too_small_image_filenames(directory, extensions=DEFAULT_IMAGE_EXTS,
                                  min_width=400, min_height=400):
    for filename in get_valid_filenames(directory, extensions):
        image_path = os.path.join(directory, filename)
        try:
            with open(image_path, 'rb') as filehandle:
                img = Image.open(filehandle)
                width, height = img.size
        except IOError, e:
                yield filename

        if (width < min_width) and (height < min_height):
            yield filename


def confirm_it(directory, extensions, images_per_dir=500):
    # Confirm selection and move files to new sub-directory

        for too_small_filename in get_too_small_image_filenames(directory):
            os.remove(os.path.join(directory, too_small_filename))

        valid_images = get_valid_filenames(directory, extensions)
        grouped_image_file_names = grouper(valid_images, images_per_dir)
        for subdir, image_filenames in enumerate(grouped_image_file_names):
            for filename in image_filenames:
                from_path = os.path.join(directory, filename)

                to_dir = os.path.join(directory, "Folder ("+str(subdir)+")")
                to_path = os.path.join(to_dir, filename)

                makedirs(to_dir)
                os.rename(from_path, to_path)


def confirm_it_wrapper():
    confirm_it(directory=folderPath.get(), extensions=extensions)

追溯:

Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Python27\lib\lib-tk\Tkinter.py", line 1486, in __call__
    return self.func(*args)
  File "C:\Users\Gavin\workspace\Test Projects\src\Test0.py", line 109, in confirm_it_wrapper
    confirm_it(directory=folderPath.get(), extensions=extensions)
  File "C:\Users\Gavin\workspace\Test Projects\src\Test0.py", line 99, in confirm_it
    from_path = os.path.join(directory, filename)
  File "C:\Python27\lib\ntpath.py", line 66, in join
    p_drive, p_path = splitdrive(p)
  File "C:\Python27\lib\ntpath.py", line 114, in splitdrive
    if len(p) > 1:
TypeError: object of type 'NoneType' has no len()

额外信息:

如前所述,我相信它来自返回zip_longest"参数的函数,其中在创建中将填充值设置为无".有什么办法可以解决这个问题吗?

As mentioned I believe it comes from the a function returning the "zip_longest" parameters where fillvalue is set to "None" in the creation. Any way around this?

谢谢.

推荐答案

问题是文件个数不是images_per_dir的倍数,所以最后一组images_per_dir 图像用 None 填充.将此 trim_grouper() 函数添加到您的代码中以解决此问题:

The problem is that the number of files is not a multiple of images_per_dir, so the last group of images_per_dir images is padded with None's. Add this trim_grouper() function to your code to take care of that:

from itertools import takewhile

def trim_grouper(iterable, n, fillvalue=None):
    for group in grouper(iterable, n, fillvalue=fillvalue):
        yield tuple(takewhile((lambda x: x), group))

然后在confirm_it()中,替换:

grouped_image_file_names = grouper(valid_images, images_per_dir)

与:

grouped_image_file_names = trim_grouper(valid_images, images_per_dir)

应该可以.

这篇关于TypeError: NoneType - 使用时返回 zip_longest的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆