在Python中,__init__是什么?【带有示例】
想要在Python中开始使用面向对象设计吗?通过学习Python的__init__方法来迈出第一步。
在本教程中,我们将介绍Python类和对象的基础知识,然后继续学习__init__方法。
通过本教程的学习,您将能够回答以下问题:
- 什么是实例变量或实例属性?
- init方法如何帮助初始化实例属性?
- 如何为属性设置默认值?
- 如何使用类方法作为构造函数来创建对象?
让我们开始吧。
Python类和对象
在Python中,类是面向对象编程的基础。我们可以创建一个类,并定义属性和方法,将数据和相关功能绑定在一起。
创建类后,我们可以将其用作创建对象(实例)的蓝图(或模板)。
👩🏫示例时间!让我们创建一个Employee类,该类的每个对象都具有以下属性:
full_name
:员工的全名,格式为姓 名
emp_id
:员工的工号department
:员工所属的部门experience
:员工的工作经验年数
这是什么意思? 🤔
每个员工将是Employee
类的一个实例或对象。每个对象将为full_name
、emp_id
、department
和experience
具有自己的值。
这些属性也称为实例变量,我们将属性和实例变量互换使用。
我们稍后将添加属性。现在我们像这样创建一个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
的内容。