PIL 和 python 静态类型

pri*_*ist 7 python typing python-imaging-library

我有一个函数参数,它可以接受多种类型的图像:

def somefunc(img: Union[np.array, Image, Path, str]):
Run Code Online (Sandbox Code Playgroud)

Image在这种情况下,PIL会引发以下异常:

TypeError: Union[arg, ...]: each arg must be a type. Got <module 'PIL.Image' from ...
Run Code Online (Sandbox Code Playgroud)

在进一步检查图像对象后,这是有道理的:

print(type(Image.open('someimage.tiff')))
>>> <class 'PIL.TiffImagePlugin.TiffImageFile'>
Run Code Online (Sandbox Code Playgroud)

我将如何为 PIL 图像指定通用类型?它来自一个文件,它的格式应该是无关紧要的。

Car*_*ate 13

我手边没有 IDE,但您遇到的错误是:

. . . Got <module 'PIL.Image'
Run Code Online (Sandbox Code Playgroud)

当您打算引用Image模块中包含的对象时,建议您尝试将模块本身用作类型。

我猜你有一个像

from PIL import Image
Run Code Online (Sandbox Code Playgroud)

这使得Image引用模块,而不是对象。

你想要类似的东西

from PIL.Image import Image
Run Code Online (Sandbox Code Playgroud)

这样对象本身就被导入了。

但请注意,现在Image指的是对象。如果要在同一文件中同时引用对象和模块,则可能需要执行以下操作:

from PIL import Image as img
from PIL.Image import Image
Run Code Online (Sandbox Code Playgroud)

现在该模块的别名为img.

  • 这是正确的,但太令人讨厌了。每个人都在代码中说“from PIL.Image import Image”。如果您使用“from PIL.Image import Image”,则任何标准代码都不起作用 - 例如“Image.open”不起作用。所以实际上你应该使用“Image.Image”作为类。感谢 PIL 的命名空间冲突。:( (6认同)

小智 6

与其他答案类似,您可以def somefunc(img: Union[np.array, Image.Image, Path, str]):直接调用模块的对象。在 python 3.9 中测试。

from PIL import Image

img = Image.open('some_path.png')
print(type(img))  # <class 'PIL.PngImagePlugin.PngImageFile'>
def to_gray(img:Image.Image):
    return img.convert("L")
img = to_gray(img)
print(type(img))  # <class 'PIL.Image.Image'>
Run Code Online (Sandbox Code Playgroud)

类型通常会随着.convert("L")