You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Jupyter Notebook无法接收util目录函数返回的PIL.Image对象问题排查

问题:PIL.Image对象返回None的排查与解决

问题场景

在pyenv管理的Python 3.10.7虚拟环境中,将函数抽象至util目录后,DownScaler类的scale方法可正常打印PIL.Image对象,但返回值始终为None,其他类型返回正常。

涉及代码

DownScaler类的scale方法:

from PIL import Image
from util.functionPerformance import functionPerformance 

class DownScaler:

    @staticmethod
    @functionPerformance
    def scale(img_path:Image ,x_factor:float, y_factor:float, verbose:bool=False) -> Image:
        picture = Image.open(img_path)
        picture.resize((int(picture.width*x_factor),int(picture.height*y_factor)))
        
        # 验证对象存在
        print(picture)                       
        return picture

Jupyter Notebook调用代码:

scaled_img = DownScaler.scale(image_path, .2, .2)
print(scaled_img)

输出结果

<PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=300x400 at 0x17EF2F4F0>
None

原因分析

  1. resize方法的非原地特性:PIL的Image.resize()是非原地修改方法,调用后会生成并返回一个新的缩放后Image对象,原picture对象不会被修改。但这不是返回None的直接原因,原代码中picture仍是有效的原始图片对象。
  2. 装饰器未传递返回值:核心问题出在@functionPerformance装饰器上。如果该装饰器仅执行了计时等逻辑,但没有将被装饰函数的返回值传递出来,装饰后的函数会默认返回None——这就是为什么函数内部能打印出有效对象,但外部接收的返回值为None。

解决方法

1. 修正resize的使用(实现缩放逻辑)

如果需要返回缩放后的图片,必须接收resize的返回值:

picture = picture.resize((int(picture.width*x_factor), int(picture.height*y_factor)))

2. 修复装饰器的返回逻辑

检查functionPerformance装饰器的实现,确保它返回被装饰函数的执行结果。标准的计时装饰器示例:

import time

def functionPerformance(func):
    def wrapper(*args, **kwargs):
        start_time = time.time()
        result = func(*args, **kwargs)  # 保存函数执行结果
        end_time = time.time()
        print(f"函数 {func.__name__} 执行耗时: {end_time - start_time:.4f} 秒")
        return result  # 必须返回结果
    return wrapper

内容的提问来源于stack exchange,提问作者FredNoonienSingh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 04:12:10