引言
在上图中可以看到一堆不同的时钟。它们有不同的形状、颜色和大小。然而,它们都是时钟。我们可以用类似的方式来考虑Python中的类。一个类表示一个类型(时钟) ,我们可以创建该类型的许多实例(不同的时钟)。
面向对象编程(OOP)范例是围绕拥有属于特定类型的对象的思想构建的。在某种意义上,类型就是解释我们为什么是对象的原因。
对象的解释对于 OOP 至关重要。我们需要全面地理解:
· 对象代表什么
· 对象存储什么样的数据
· 如何与对象交互
· 如何在代码中实现对象
构成对象解释的所有这些点都是用类定义的。Python中的所有内容都是一个类型的对象,例如整数,列表,字典,函数等。我们使用类定义对象的类型。
在本文中,我们将探讨类的含义,如何在Python中创建和使用类以及通过使用类可以获得哪些优势。
Python中的类是什么?
类具有以下信息:
· 数据属性:创建类实例所需的内容
· 方法(即过程属性):我们如何与类实例进行交互
我们一直在使用Python中的类。例如,当我们创建一个列表时,我们将创建一个类型为list的实例。
words = ['data', 'science', 'machine', 'learning']
我们实际上对列表类的创建方式不感兴趣。我们只需要知道如何与列表交互并在我们的代码中有效地使用它们即可。这就是抽象的概念。
例如,我们可以使用remove方法从列表中删除一个项目。
words.remove('data')
print(words)
['science', 'machine', 'learning']
创建一个类
下面的代码创建一个名为Book的类。
class Book():
def __init__(self, name, writer, word_length):
self.name = name
self.writer = writer
self.word_length = word_length
__init__是一个特殊的函数,当创建类的实例时,该函数会自动执行。它也称为类构造函数。
init函数的参数表示类的数据属性。因此,如果需要为name,writer和length参数指定参数以创建Book实例。
注意:self是指实例本身。可以使用任何单词代替“self”,但是使用“self”是一种非常普遍的做法。
让我们创建一个实例。
b1 = Book("Pandas", "John Doe", 100000)
print(type(b1))
<class '__main__.Book'>
b1是属于Book类的对象。我们可以使用返回对象类型的类型函数进行确认。
我们可以使用以下方法访问或修改类的属性。
print(b1.name)
Pandas
b1.name = 'NumPy' #updates the name attribute
print(b1.name)
NumPy
定义类方法
Book类仅具有数据属性。我们应该添加方法(即过程属性),使其具有实用性和功能性。
例如,我们可以实现一种方法,该方法返回给定fontsize的页数。我们用字数指定书的长度。该方法将根据长度和字体大小计算页面数。
def number_of_pages(self, fontsize=12):
word_length = self.word_length
if fontsize == 12:
words_in_page = 300
else:
words_in_page = 300 - (fontsize - 12) * 10
return round(word_length / words_in_page)
我们在类定义中添加number_of_pages。它根据单词数和字体大小计算一本书的页数。
如果我们在类定义中声明的函数需要访问实例的数据属性,则需要告诉该函数如何访问它们。这是我们在number_of_pages函数的第一行中所做的。
我们可以从类或实例访问方法。
b1 = Book("Pandas", "John Doe", 100000)
b1.number_of_pages()
333
Book.number_of_pages(b1)
333
number_of_pages函数具有一个附加的fontsize参数。由于指定了默认值(12),因此我们不必显式编写它。但是,我们可以为fontsize参数使用不同的值。
b1.number_of_pages(14)
357
b1.number_of_pages(fontsize=16)
385
随着字体大小的增加,页面数量也会增加。
为了使用Python的某些内置函数,我们需要为类定义某些方法。考虑打印功能。
print(b1)
<__main__.Book object at 0x7fa4cf9f7588>
默认情况下,打印功能返回对象的类型和存储位置。但是,我们可以通过在类中实现__str__方法来自定义其行为。
def __str__(self):
return "<" + self.name + ", by " + self.writer + ">"
如上所述,我们在类定义中添加了_str_方法。以下是print函数现在在我们的类中的工作原理:
print(b1)
<Pandas, by John Doe>
类与实例变量
类变量在类内部但在任何函数外部声明。实例变量是在__init__方法的构造函数中声明的。
类变量更为通用,可能会应用类的所有实例。另一方面,实例变量更为具体,并分别为每个实例定义。在类变量和实例变量之间进行区分非常有用。
考虑我们之前定义的Book类。我们经营一家出版公司,并为我们出版的书籍制定了一些标准,例如封面的页面宽度和颜色。如果将它们定义为类变量,则不必为创建的每个实例显式声明。
class Book():
page_width = 14
cover_color = "blue"
def __init__(self, name, writer, word_length):
self.name = name
self.writer = writer
self.word_length = word_length
我们已将page_width和cover_color实现为类变量,因为它们位于类定义之内,但不在任何函数定义之内。
让我们创建 Book 类的一个实例。
b2 = Book("Machine Learning", "Jane Doe", 120000)
在创建此实例时,我们没有指定类变量。然而,b2拥有这些变量,我们可以访问它们。
b2.page_width
14
b2.cover_color
'blue'
我们可以选择更改特定实例的类变量。
b2.cover_color = 'red'
b2.cover_color
'red'
对特定实例的更改不会对类变量产生任何影响。
Book.cover_color
'blue'
创建一个子类
我们可以基于不同的类创建一个类。让我们基于“ Book”类创建一个名为“ ColorBook”的类。
class ColorBook(Book):
ColorBook是Book类的子类。当我们以这种方式创建一个类时,子类从父类复制属性(数据和过程)。这个概念称为继承,它使OOP更加有效和强大。
它与现实生活中的遗传类似。我们的基因组大部分来自我们的父母或祖先。我们从他们那里继承。因此,我们和我们的父母有相似之处。
除了从父类继承的属性之外,子类还可以有新的属性。此外,我们还可以选择修改或覆盖继承的属性。
让我们定义ColorBook类的__init__函数。它将具有两个附加参数,分别是“ color”(颜色)指示页面的颜色和“ has_image”(指示书中是否有图像)。
class ColorBook(Book):
def __init__(self, name, writer, word_length, color, has_image):
Book.__init__(self, name, writer, word_length
self.color = color
self.has_image = has_image
由于name,writer和word_length已在Book类中定义,因此我们可以从中复制__init__方法。我们只需要定义其他属性。
注意:我们可以自由为子类手动定义每个数据属性。使用父节点的__init__是可选的。
让我们创建一个ColorBook类的实例。
c1 = ColorBook("Seaborn", "John Doe", 90000, "green", True)
c1.name
"Seaborn"
c1.color
"green"
子类也继承类变量。
c1.cover_color
"blue"
c1.page_width
14
这些方法也是从父类复制的。对于Book类,我们定义了两个方法,它们也可以用于ColorBook类的实例。
c1.number_of_pages()
300
print(c1)
<Seaborn, by John Doe>
我们可以选择覆盖从父类继承的数据和过程属性(即方法)。这使继承更加强大,因为我们必须使用父类中的所有内容。
例如,我们可以为ColorBook类修改__str__方法。
def __str__(self):
return "<" + self.name + ", in " + self.color + ">"
Print函数将返回书的名称和颜色。
c1 = ColorBook("Seaborn", "John Doe", 90000, "green", True)
print(c1)
<Seaborn, in green>
下面是Book和ColorBook类的类定义。
总结
我们在本文中讨论的内容可以被认为是对 Python 类的全面介绍。我们已经提到了类对于面向对象编程的重要性,以及类如何演示抽象和继承等关键概念。
在实际应用方面,我们已经定义了两个类,并且看到了在创建子类时继承是如何工作的。
还有很多关于 Python 类的内容。一旦你熟悉了这些基础知识,就可以自由地进入更高级的话题。
· END ·
HAPPY LIFE