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__与类中其他普通方法的区别在于:
- __init__在生成类实例的时候自动被调用,而普通方法需要被显示调用才能起到作用。
- __init__传入的参数为局部变量,如果想要在类中的其他方法中使用该变量,需要赋值给self.<属性名>
- __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