在Python中,__init__是什么?【带有示例】

想要在Python中开始使用面向对象设计吗?通过学习Python的__init__方法来迈出第一步。

在本教程中,我们将介绍Python类和对象的基础知识,然后继续学习__init__方法。

通过本教程的学习,您将能够回答以下问题:

  • 什么是实例变量或实例属性?
  • init方法如何帮助初始化实例属性?
  • 如何为属性设置默认值?
  • 如何使用类方法作为构造函数来创建对象?

让我们开始吧。

Python类和对象

在Python中,类是面向对象编程的基础。我们可以创建一个类,并定义属性和方法,将数据和相关功能绑定在一起。

创建类后,我们可以将其用作创建对象(实例)的蓝图(或模板)。

👩‍🏫示例时间!让我们创建一个Employee类,该类的每个对象都具有以下属性:

  • full_name:员工的全名,格式为姓 名
  • emp_id:员工的工号
  • department:员工所属的部门
  • experience:员工的工作经验年数

这是什么意思? 🤔

每个员工将是Employee类的一个实例或对象。每个对象将为full_nameemp_iddepartmentexperience具有自己的值。

这些属性也称为实例变量,我们将属性和实例变量互换使用。

我们稍后将添加属性。现在我们像这样创建一个Employee类:

class Employee:
    pass

使用pass(作为占位符)可以帮助我们在运行脚本时避免错误。

虽然当前版本的Employee类并不是很有用,但它仍然是一个有效的类。因此,我们可以创建Employee类的对象:

employee_1 = Employee()

print(employee_1)
#输出:

我们也可以添加属性并将其初始化为特定值,如下所示:

employee_1.full_name = 'Amy Bell'
employee_1.department = 'HR'

但是,这种添加实例属性的方法既低效又容易出错。此外,这种方法不允许使用类作为模板来创建对象。这就是__init__方法的用处所在。

理解Python类中__init__方法的作用

我们应该能够在实例化对象时初始化实例变量,而__init__方法可以帮助我们实现这一点。每当创建类的新对象时,__init__方法被调用以初始化实例变量的值。

如果您以前使用过像C++这样的语言,您会发现__init__方法的工作方式类似于构造函数。

定义__init__方法

让我们将__init__方法添加到Employee类中:

class Employee:
    def __init__(self, full_name,emp_id,department,experience):
        self.full_name = full_name
        self.emp_id = emp_id
        self.department = department
        self.experience = experience

self参数指的是类的实例,而self.attribute将实例的attribute初始化为右侧的值。

现在我们可以这样创建对象:

employee_2 = Employee('Bella Joy','M007','Marketing',3)
print(employee_2)
# 输出: 

当我们打印出员工对象时,除了它们所属的类之外,我们不会得到任何有用的信息。让我们添加一个__repr__方法为该类定义一个表示字符串:

 def __repr__(self):
        return f"{self.full_name},{self.emp_id} from {self.department} with {self.experience} years of experience."

__repr__添加到Employee类中,我们有:

class Employee:
    def __init__(self, full_name,emp_id,department,experience):
        self.full_name = full_name
        self.emp_id = emp_id
        self.department = department
        self.experience = experience
    
     def __repr__(self):
        return f"{self.full_name},{self.emp_id} from {self.department} with {self.experience} years of experience."

现在员工对象有一个有用的表示字符串:

print(employee_2)
# 输出: Bella Joy,M007 from Marketing with 3 years of experience.

一些约定

在我们继续之前,这里有几点需要注意:

  • 我们在__init__方法中使用self作为第一个参数,以引用类实例本身,并使用self.attribute_name来初始化各种属性。使用self是首选的约定(你可以使用任何其他名称)。
  • 在定义__init__方法时,我们将参数名称设置为__init__定义中的属性名称。这提高了可读性。

如何为属性添加默认值

在我们目前编写的示例中,所有的属性都是必需的。这意味着只有当我们为构造函数传递了所有字段的值时,才能成功创建对象。

尝试实例化一个Employee类的对象,而不为experience属性传递值:

employee_3 = Employee('Jake Lee','E001','Engineering')

你会得到以下错误:

Traceback (most recent call last):
  File "main.py", line 22, in 
    employee_3 = Employee('Jake Lee','E001','Engineering')
TypeError: __init__() missing 1 required positional argument: 'experience'

但是,如果你想使某些属性可选,可以在定义__init__方法时为这些属性提供默认值。

这里我们为experience属性提供了默认值0

class Employee:
    def __init__(self, full_name,emp_id,department,experience=0):
        self.full_name = full_name
        self.emp_id = emp_id
        self.department = department
        self.experience = experience
    
     def __repr__(self):
        return f"{self.full_name},{self.emp_id} from {self.department} with {self.experience} years of experience."

创建的employee_3对象没有为experience属性提供值;使用默认值0代替。

employee_3 = Employee('Jake Lee','E001','Engineering')
print(employee_3.experience)
# 输出: 0

使用类方法添加替代类构造函数

到目前为止,我们只看到了如何定义__init__方法并在需要时设置属性的默认值。我们也知道我们需要在构造函数中传入必需属性的值。

然而,有时这些实例变量(或属性)的值可能存在于不同的数据结构中,比如元组、字典或JSON字符串。

我们该怎么办呢?

让我们来看一个例子。假设我们在Python字典中有实例变量的值:

dict_fanny = {‘name':'Fanny Walker','id':'H203′,'dept':'HR','exp':2}

我们可以从字典中获取所有属性的值,如下所示:

name = dict_fanny[‘name'] id = dict_fanny[‘id'] dept = dict_fanny[‘dept'] exp = dict_fanny[‘exp']

在此之后,您可以通过将这些值传递给类构造函数来创建一个对象:

employee_4 = Employee(name, id, dept, exp)
print(employee_4)
# 输出:Fanny Walker,H203,从HR获得2年的经验。

请记住:对于每个新创建的对象,您都需要执行此操作。这种方法效率低下,我们肯定可以做得更好。但是怎么做呢?

在Python中,我们可以使用类方法作为构造函数来创建类的对象。要创建一个类方法,我们使用@classmethod装饰器。

让我们定义一个方法,该方法解析字典,获取实例变量的值,并使用这些值来构造Employee对象。

@classmethod
def from_dict(cls,data_dict):
full_name = data_dict[‘name'] emp_id = data_dict[‘id'] department = data_dict[‘dept'] experience = data_dict[‘exp'] return cls(full_name, emp_id, department, experience)

当我们需要使用字典中的数据来创建对象时,我们可以使用from_dict()类方法。

注意:在类方法中使用cls而不是self。就像我们使用self来引用实例一样,cls用于引用类。此外,类方法绑定到类而不是对象。

因此,当我们调用类方法from_dict()来创建对象时,我们调用它的类Employee

emp_dict = {‘name':'Tia Bell','id':'S270′,'dept':'Sales','exp':3}
employee_5 = Employee.from_dict(emp_dict)
print(employee_5)
# 输出:Tia Bell,S270,从Sales获得3年的经验。

现在,如果我们为每个n个员工都有一个字典,我们可以使用from_dict()类方法作为构造函数来实例化对象,而不必从字典中检索实例变量的值。

关于类变量的说明

在这里,我们定义了绑定到类而不是个别实例的类方法。类似于类方法,我们还可以有类变量。

像类方法一样,类变量绑定到类而不是实例。当一个属性对于类的所有实例都有固定的值时,我们可以考虑将它们定义为类变量。

常见问题解答

1. 为什么需要Python中的__init__方法?

类定义中的__init__方法允许我们初始化所有实例的属性或实例变量。每次创建类的新实例时都会调用__init__方法。

2. 在Python类中可以有多个__init__方法吗?

在Python类中有多个__init__方法的目标是提供多个构造函数来实例化对象。但是你不能定义多个__init__方法。如果你定义多个__init__方法,第二个和最近的实现将会覆盖第一个。然而,你可以使用@classmethod装饰器来定义类方法,这些方法可以用作构造函数来实例化对象。

3. 如果在类中不定义__init__方法会发生什么?

如果你不定义__init__方法,你仍然可以实例化对象。然而,你将不得不手动添加实例变量并为每个变量赋值。你将无法在构造函数中为实例变量传入值。这不仅容易出错,而且违背了将类作为蓝图实例化对象的目的。

4. 在__init__方法中可以为参数设置默认值吗?

是的,在定义__init__方法时可以为一个或多个属性提供默认值。提供默认值可以使这些属性在构造函数中变为可选的。当我们在构造函数中不为这些属性传入值时,这些属性将取默认值。

5. 可以在__init__方法外修改属性吗?

是的,你总是可以在__init__方法之外更新属性的值。你还可以在创建特定实例后动态地添加新属性。

结论

在本教程中,我们学习了如何使用__init__方法来初始化实例变量的值。虽然这很简单,但当你有很多属性时可能会重复。

如果你感兴趣,可以探索dataclasses module。在Python 3.7及更高版本中,你可以使用内置的数据类模块来创建存储数据的数据类。除了__init__和其他常用方法的默认实现外,它们还具有许多用于类型提示、复杂默认值和优化的很酷功能。

接下来,了解更多关于if __name__==’__main__’ in Python的内容。

类似文章