Python 语法问题:类实例化及其参数在括号外 [duplicate]

python syntax question: class instantiation with its argument outside brackets [duplicate]

提问人:Dummy 提问时间:10/20/2022 更新时间:10/20/2022 访问量:55

问:

我无法弄清楚使用哪种python sytanx。 我希望有人能告诉我。

from pathlib import Path

import matplotlib.pyplot as plt
import numpy as np

import torch
import torchvision.transforms as T
from torchvision.io import read_image


plt.rcParams["savefig.bbox"] = 'tight'
torch.manual_seed(1)


def show(imgs):
    fix, axs = plt.subplots(ncols=len(imgs), squeeze=False)
    for i, img in enumerate(imgs):
        img = T.ToPILImage()(img.to('cpu'))
        axs[0, i].imshow(np.asarray(img))
        axs[0, i].set(xticklabels=[], yticklabels=[], xticks=[], yticks=[])

我想知道的部分在下面。

        img = T.ToPILImage()(img.to('cpu'))

ToPILImage()类实例化图像对象,不是作为其参数,而是在括号外。

代码来自此页面。
https://pytorch.org/vision/stable/auto_examples/plot_scripted_tensor_transforms.html#sphx-glr-auto-examples-plot-scripted-tensor-transforms-py

的源代码来自下面的页面链接。
https://pytorch.org/vision/stable/_modules/torchvision/transforms/transforms.html#ToPILImage
ToPILImage()

在该页上,仅定义了类的三个特殊方法 (、 、)。__init____call____repr__

class ToPILImage:
    """Convert a tensor or an ndarray to PIL Image. This transform does not support torchscript.

    Converts a torch.*Tensor of shape C x H x W or a numpy ndarray of shape
    H x W x C to a PIL Image while preserving the value range.

    Args:
        mode (`PIL.Image mode`_): color space and pixel depth of input data (optional).
            If ``mode`` is ``None`` (default) there are some assumptions made about the input data:
            - If the input has 4 channels, the ``mode`` is assumed to be ``RGBA``.
            - If the input has 3 channels, the ``mode`` is assumed to be ``RGB``.
            - If the input has 2 channels, the ``mode`` is assumed to be ``LA``.
            - If the input has 1 channel, the ``mode`` is determined by the data type (i.e ``int``, ``float``,
            ``short``).

    .. _PIL.Image mode: https://pillow.readthedocs.io/en/latest/handbook/concepts.html#concept-modes
    """

    def __init__(self, mode=None):
        _log_api_usage_once(self)
        self.mode = mode

    def __call__(self, pic):
        """
        Args:
            pic (Tensor or numpy.ndarray): Image to be converted to PIL Image.

        Returns:
            PIL Image: Image converted to PIL Image.

        """
        return F.to_pil_image(pic, self.mode)

    def __repr__(self) -> str:
        format_string = self.__class__.__name__ + "("
        if self.mode is not None:
            format_string += f"mode={self.mode}"
        format_string += ")"
        return format_string

我的猜测是

  • 在该过程中调用。__init__
  • 对象强制转换正在进行中。

但我不知道这两者在那次通话中是如何联系在一起的?

Python 语法 转换

评论

0赞 Abirbhav G. 10/20/2022
没有进行对象投射。该对象只是简单地调用它的魔术方法。它是尝试将对象作为函数运行时调用的魔术函数。ToPILImage__call__
0赞 Dummy 10/20/2022
@AbirbhavG。哦。。它不是,而是.从未使用过特殊方法。__init____call__
0赞 Dummy 10/20/2022
@Woodford感谢您的参考!我通读了它。有了这个参考和亚历克·彼得森的回答,它就清楚了!

答:

1赞 John Gordon 10/20/2022 #1
img = T.ToPILImage()(img.to('cpu'))

T.ToPILImage()必须返回一些可调用的对象(可能是一个类)。

然后调用这个对象,并作为参数。img.to('cpu')

如果有帮助,请这样考虑代码:

myclass = T.ToPILImage()
img = myclass(img.to('cpu'))

评论

0赞 Dummy 10/20/2022
谢谢,示例代码非常容易理解!
1赞 Alec Petersen 10/20/2022 #2

它不是使用图像对象作为参数进行实例化。该类被实例化(这是运行时),然后以图像作为参数(如函数)调用它(因此是方法的实现)。T.ToPILImage()__init____call__

一个简单的例子:

class Add:
    def __call__(self, x, y):
        return x + y

adder = Add()
summed = adder(1, 3)
print(summed)

评论

0赞 Dummy 10/20/2022
谢谢!!!这个例子都是有道理的。