我现在收到NoneType的类型错误(我假设当我尝试在zip_longest函数中返回一个值时)
我的代码的目标是删除小于“width = 400 AND height = 400”的图像文件,然后将所有剩余的图像放入x值的文件夹中(其中x可以在以后更改)。目前代码似乎工作,但我得到了我提到的问题,并希望防止该错误。
代码:
# ======== 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”参数的函数,其中fillvalue在创建中设置为“None”。有什么方法吗?
感谢。
答案 0 :(得分:1)
问题是文件数量不是images_per_dir
的倍数,因此最后一组images_per_dir
图片会填充None
个。{将此trim_grouper()
函数添加到您的代码中以处理该问题:
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)
应该这样做。