天天看点

Pytorch学习(五)内置函数__init__()和__call__()函数的使用

1. __init__的用法

首先按照如下方法定义一个类Student并初始化该类的一个对象stu,通过语句stu.scores为stu添加属性,这个类存在的问题是:我们还可以为stu1, stu2不同的实例化对象添加不同的属性,但理论上,stu, stu1, stu2属于同一类Student,我们希望他们具备相同的属性,如name, scores。而且采用这种设置对象属性的方式,scores等属性是暴露的,没有起到封装的效果。

class Student:
    pass
stu = Student()
stu.scores = [84,86,95]
print(stu.scores)
           

上述问题的解决方案就是在实例化的时候对类传入一些参数,来设置实例化对象的属性,这种初始化方法通过__init__实现。

在定义类的时候,如果添加__init__方法,在创建类的实例时,会自动调该方法,通常用来对类的属性进行初始化,以下边的Student类为例。

class Student:
	def __init__(self, name, scores):
		self.name = name
		self.scores = scores
stu = Student()  
           

__init__方法中的第一个参数self指向新创建的实例化对象,self也可以换成其他名称,但习惯上使用self。通过语句stu = Student() 可以创建Student类的实例。

__init__与类中其他普通方法的区别在于:

  1. __init__在生成类实例的时候自动被调用,而普通方法需要被显示调用才能起到作用。
  2. __init__传入的参数为局部变量,如果想要在类中的其他方法中使用该变量,需要赋值给self.<属性名>
  3. __init__不允许有返回值

2. __call__的用法

根据下面的代码可以看出,call()函数不用显示调用,而是使用对象初始化的方式来调用。

class Person:
    def __call__(self, name):
        print("__call__" + " hello " + name)

    def hello(self, name):
        print("hello ", name)

p = Person()
p("Amy")
p.hello("Mike")

# 结果如下:
__call__ hello Amy
hello  Mike

           

可以结合torchvision.transforms里的compose()来深入理解__init__()和__call__()的用法

class Compose(object):
    """Composes several transforms together.

    Args:
        transforms (list of ``Transform`` objects): list of transforms to compose.

    Example:
        >>> transforms.Compose([
        >>>     transforms.CenterCrop(10),
        >>>     transforms.ToTensor(),
        >>> ])
    """

    def __init__(self, transforms):
        self.transforms = transforms

    def __call__(self, img):
        for t in self.transforms:
            img = t(img)
        return img

    def __repr__(self):
        format_string = self.__class__.__name__ + '('
        for t in self.transforms:
            format_string += '\n'
            format_string += '    {0}'.format(t)
        format_string += '\n)'
        return format_string

           
下一篇: .net 02