_init_()的目的是什么?

时间:2017-12-20 18:31:09

标签: python

嘿伙计们,所以我对_init_()进行了大量研究,但仍然没有得到它。从我目前的理解,它必须用于所有类的实例传递对象args?

我理解self的用法,但无论出于何种原因,我似乎无法绕过_init_()。为什么我们必须使用它。它何时有用,除了实例化类的实例之外,它的用途是什么?

如果在调用_init_()之前已经创建了所述对象,它是如何构造函数的?

一般来说,我只是不知道_init_()背后的原因,方式或时间,而不是用于实例化类的实例,它可以有多个args,它们似乎特定于实例班级。必须为每个实例调用它?

2 个答案:

答案 0 :(得分:1)

我不是这方面的专家,但是AFAIK __init__方法是每个类或元类的内置方法,在类实例化中完全被称为。

为什么或使用__init__方法?

好吧,你可以将它用于很多事情,但主要目的是在实例化时将参数传递给类实例。实际上当你执行class(*args, **kwargs)时,这些内容会被传递到__init__,您可以在其中使用或不使用它们。

例如:

class Vehicle:

    name = 'vehicle'
    price = None
    canMove = False
    position = 0

    def __init__(self, price, name=None, canMove=False):
        self.name = name if name else self.name
        self.price = price

    def move(self, distance):
        if self.canMove:
            self.position += distance
            return 'The vehicle moved {0} meters'.format(distance)
        return 'The vehicle cannot move'


class Car(Vehicle):
    name = 'car'
    consumption = 100 # (litres per meter)
    fuel = 0 # (litres )

    def __init__(self, fuel, consumption=None, *args, **kwargs):
        self.fuel = fuel
        self.consumption = consumption if consumption else self.consumption
        super().__init__(*args, **kwargs)

    def move(self, distance):
        if self.canMove and self.hasFuel():
            available_d = self.fuel / self.consumption
            if distance <= available_d:
                self.fuel -= self.consumption*distance
                self.position += distance
                return 'The vehicle moved {0} meters and has {1} litres left.'.format(distance, self.fuel)
            return 'The vehicle cannot move since it does not have fuel enough'
        return 'The vehicle cannot move since it does not have any fuel'


    def hasFuel(self):
        return True if self.fuel > 0 else False

    def giveFuel(self, litres):
        self.fuel += litres

如果您花一些时间阅读代码,您将看到如何在__init__方法中运行必要的任务,例如变量赋值,执行检查或运行其他进程。

此外,当您从另一个类继承时,行为会变得更复杂一些。如你所见,我必须通过super().__init__()调用来调用母班,以便运行其中正在完成的其余任务。

__init__正在使用

让我们来玩这个我刚刚创建的代码。

您可以像这样制作您的车辆:

myVehicle = Vehicle()

然而,这会引发错误,因为__init__方法需要传递一个强制参数price。所有其余的都是可选字段,但这对于实例化是必须的。因此,你可以再试一次:

myVehicle = Vehicle(10000)

您可以访问刚刚传递的值:

myVehicle.price

您也可以传递其余元素,但它们不是强制性的:

myVehicle2 = Vehicle(10000, name='myVehicle2', canMove=True)

请记住,我们也可以在实例化之后将它们分配给我们的第一辆车:

myVehicle.name = 'myVehicle'

所以现在我们有两种不同的车辆,但是一辆可以移动,另一辆则不能。如果我们运行,我们可以看到这一点:

myVehicle.move(100)

myVehicle2.move(100)不会引发错误。如果您之后更改了第一辆车的属性,无论您最初传递给__init__的值是什么,它都会起作用。

它与我们的Car类相似。如果我们Car()

>>> Car()
Traceback (most recent call last):
  File "<input>", line 1, in <module>
TypeError: __init__() missing 1 required positional argument: 'fuel'

即使我们Car(fuel=140)

>>> Car(fuel=140)
Traceback (most recent call last):
  File "<input>", line 1, in <module>
  File "<input>", line 10, in __init__
TypeError: __init__() missing 1 required positional argument: 'price'

所有这些参数都在__init__部分中定义,price标记是必需的,因为它从父类继承。

当我们尝试移动汽车时,看看价值如何正常运作:

>>> myCar = Car(price=10000, fuel=150, consumption=10)
>>> myCar.move(10)
'The vehicle cannot move since it does not have any fuel' # we actually have not enabled its canMove property
>>> myCar.canMove = True
>>> myCar.move(10)
'The vehicle moved 10 meters and has 50 litres left.'
>>> myCar.move(1)
'The vehicle moved 1 meters and has 40 litres left.'
>>> myCar.move(30)
'The vehicle cannot move since it does not have fuel enough'

答案 1 :(得分:0)

当创建该类型的对象时会调用它,因此您可以执行任何需要特定于类的初始化,并且不必记住进行单独的初始化调用。这就是它的用途;这就是它的目的。