共计 8130 个字符,预计需要花费 21 分钟才能阅读完成。
作者 |HIMANSHI SINGH
编译 |VK
起源 |Analytics Vidhya
介绍
在学习面向对象编程时,我决定深入研究它的历史,后果发现它很迷人。术语“面向对象编程”(OOP)是 Alan Kay 在 1966 年研究生院时提出的。
Simula 语言是第一种具备面向对象编程特点的编程语言。它是在 1967 年开发的,用于制作模拟程序,其中最重要的信息称为对象。
只管 OOPS 自 20 世纪 60 年代初就在市场上,但在 20 世纪 90 年代,OOPS 开始因为 C ++ 而增长。
除此之外,这种编程技术曾经被包含 Python 在内的各种编程语言所采纳,它的利用简直遍布所有畛域,如实时零碎、人工智能、专家系统、CS 零碎、面向对象数据库等等。
因而,在本文中,我将解释 Python 中面向对象编程的基本概念。
目录
- 什么是面向对象编程?
- 面向对象编程 (OOP) 与面向过程编程(POP)
-
OOPs 的次要概念
- 什么是类?
- 对象和对象实例化
- 类办法
- Python 类中的继承
- 封装
- 多态性
- 数据抽象
什么是面向对象编程?
面向对象编程 (OOP) 就是创立“对象”。对象是一组互相关联的变量和函数。这些变量通常称为对象的属性,函数称为对象的行为。这些对象为程序提供了一个更好、更清晰的构造。
例如,汽车能够是一个对象。如果咱们把汽车当作一个对象,那么它的属性就是——色彩、型号、价格、品牌等等,它的行为 / 函数是减速、加速、换挡。
另一个例子——如果咱们把狗当作一个物体,那么它的属性就是——它的色彩、种类、名字、体重等,而它的行为 / 函数是行走、吠叫、游玩等。
面向对象编程因其在编程中实现了对象、暗藏、继承等事实实体而闻名。它使可视化更容易,因为它靠近真实世界的场景。
面向对象编程 (OOP) 与面向过程编程(POP)
OOP 和过程式编程的根本区别是
- 一种思考 POP 的办法就是你做柠檬水的形式。制作柠檬水的过程包含——首先依据须要取水,而后在水中退出糖,而后在混合物中退出柠檬汁,最初将整个溶液混合。这样你的柠檬水就筹备好了。同样,POP 也须要肯定的步骤。程序程序由函数组成。这意味着在 POP 办法中,程序被划分为特定于不同工作的函数。这些性能按特定的顺序排列,程序的管制按程序进行。
- 而 OOP 程序是由对象组成的。面向对象办法将程序划分为对象。这些对象是将事实世界对象的属性和行为捆绑在一起的实体。
- POP 只实用于小工作。因为随着程序长度的减少,代码的复杂性也随之减少。最初变成了一个函数网。而且,它变得很难调试。OOP 通过更清晰、以更不简单的构造来解决这个问题。它容许以继承的模式从新应用代码。
- 另一个重要的是,在面向过程的编程中,所有函数都能够拜访所有数据,这意味着不足安全性。假如你想爱护来自世界各地的凭据或任何其余要害信息。那么程序化办法就不能为你提供这种安全性。因为这个 OOP 帮忙你实现了一个称为封装的惊人性能,它容许咱们暗藏数据。不必放心,在本文的后半局部,我将具体介绍这一点以及面向对象编程的其余概念。当初,只需了解 OOP 反对安全性,POP 不反对。
- 编程语言如 C、Pascal 和 Basic 应用过程办法,而 java、Python、JavaScript、PHP、Scala 和 C ++ 是提供面向对象办法的次要语言。
OOPs 的次要概念
在本节中,咱们将深入探讨 OOP 的基本概念。咱们将探讨以下主题
- 类
- 对象
- 办法
- 继承
- 封装
- 多态性
- 数据抽象
1. 什么是类?
这个问题的间接答案是:类是对象的汇合。与原始数据构造不同,类是用户定义的数据结构。它们使代码更易于治理。
让咱们看看如何定义上面的类
class class_name:
class body
咱们用关键字“class”在类名和分号前面定义一个类。在应用缩进之后,咱们会思考有缩进的所有货色。为了让这更容易了解,让咱们看一个例子。
以汽车展厅为例。你要存储每辆车的详细信息。让咱们首先定义一个类
class Car:
pass
就这样!
留神:我用 pass 语句代替了它的主体,因为次要目标是展现如何定义一个类,而不是它应该蕴含什么。
在具体介绍之前,首先要理解对象和实例化。
2. 对象和对象实例化
当咱们定义一个类时,只会创建对象的形容或蓝图,在这个过程中没有内存调配。而对象实例具备内存调配,它蕴含实在的数据或信息。
实例化是创立一个类的实例。让咱们创立下面定义的类的对象 -
obj1 = Car()
这样就创立了一个对象实例。请留神,你能够依据你的抉择更改对象名称。
尝试打印此对象
print(obj1)
因为咱们的类是空的,所以它返回存储对象的地址,即 0x7fc5e677b6d8
在持续学习之前,你还须要理解类的构造函数。
类构造函数
到目前为止,咱们有一辆空的车,是时候把车的特色填满咱们的类了。类构造函数的工作是在创立类的对象时将值调配给类的数据成员。
一辆车能够有不同的属性,如名称、色彩、型号、品牌、发动机功率、分量、价格等。咱们将仅抉择其中几项以便于了解。
class Car:
def __init__(self, name, color):
self.name = name
self.color = color
因而,car 或任何其余对象的属性必须位于一个咱们称为 __init__()的办法中。此办法也称为构造函数办法。每当类的对象被结构时,就调用构造函数办法。
当初,让咱们来讨论一下 __init__()办法的参数。所以,这个办法的第一个参数必须是 self。而后才是剩下的参数
构造函数办法中的两个语句是
- self.name = name
- self.color = color:
这将创立新的属性,即 name 和 color,而后将参数的值调配给它们。“self”关键字示意类的实例。通过应用“self”关键字,咱们能够拜访类的属性和办法。它在办法定义和变量初始化中很有用。“self”在每次定义方法时都显式应用。
留神:你也能够在此办法之外创立属性。然而这些属性对整个类都是通用的,必须给它们赋值。
假如你的展厅中的所有汽车都是 Sedan,而不是一次又一次地指定它,你能够通过创立一个属性来将 car_type 的值固定为 Sedan。
class Car:
car_type = "Sedan" #类属性
def __init__(self, name, color):
self.name = name #实例属性
self.color = color #实例属性
这里,实例属性是指构造函数办法中的属性,在这个例子中是 self.name 和 self.color。类属性是指构造函数办法之外的属性,在这个例子中是 car_type。
3. 类办法
到目前为止,咱们曾经增加了汽车的属性。当初是时候增加一些行为了。办法是咱们用来形容对象行为的函数。它们也在类中定义。请看上面的代码
class Car:
car_type = "Sedan"
def __init__(self, name, mileage):
self.name = name
self.mileage = mileage
def description(self):
return f"The {self.name} car gives the mileage of {self.mileage}km/l"
def max_speed(self, speed):
return f"The {self.name} runs at the maximum speed of {speed}km/hr"
在类中定义的办法 (而不是构造函数办法) 称为实例办法。此外,这里有两个实例办法,description()和 max_speed()。
- description()—此办法返回一个字符串,其中蕴含汽车的形容,如名称和里程数。此办法没有其余参数。此办法正在应用实例属性。
- max_speed()—此办法有一个附加参数,并返回一个显示车辆名称及其速度的字符串。
请留神,附加参数 speed 没有应用“self”关键字。因为 speed 不是一个实例变量,所以咱们不应用 self 关键字作为前缀。让咱们为下面形容的类创立一个对象。
obj2 = Car("Honda City",24.1)
print(obj2.description())
print(obj2.max_speed(150))
咱们所做的是创立一个类 car 的对象并传递所需的参数。为了应用 object_name.method_name().
description()办法没有任何附加参数,因而在调用它时没有传递任何参数。
max_speed()办法有一个附加参数,因而咱们在调用它时传递了一个参数。
留神:三件重要的事要记住
- 能够创立一个类的任意数量的对象。
- 如果办法须要 n 个参数,而你没有传递雷同数量的参数,则会产生谬误。
- 参数的程序很重要。
让咱们一个个来看看
- 创立一个类的多个对象
class Car:
def __init__(self, name, mileage):
self.name = name
self.mileage = mileage
def max_speed(self, speed):
return f"The {self.name} runs at the maximum speed of {speed}km/hr"
Honda = Car("Honda City",21.4)
print(Honda.max_speed(150))
Skoda = Car("Skoda Octavia",13)
print(Skoda.max_speed(210))
- 参数数目谬误
class Car:
def __init__(self, name, mileage):
self.name = name
self.mileage = mileage
Honda = Car("Honda City")
print(Honda)
因为咱们没有提供第二个参数,所以咱们失去了这个谬误。
- 参数程序
class Car:
def __init__(self, name, mileage):
self.name = name
self.mileage = mileage
def description(self):
return f"The {self.name} car gives the mileage of {self.mileage}km/l"
Honda = Car(24.1,"Honda City")
print(Honda.description())
搞混了!因为咱们扭转了论点的程序。
当初,面向对象编程有四个基本概念:继承、封装、多态和数据抽象。为了了解 OOPs,理解所有这些十分重要。到目前为止,咱们曾经介绍了面向对象编程的基本知识,让咱们进一步深刻。
4. Python 类中的继承
继承是一个类继承另一个类的属性和办法的过程。被继承的类称为父类。从父类继承属性的类是子类。
乏味的是,除了继承的属性和办法外,子类能够有本人的属性和办法。
如何继承父类?应用以下语法:
class parent_class:
body of parent class
class child_class(parent_class):
body of child class
让咱们看看实现
class Car: #父类
def __init__(self, name, mileage):
self.name = name
self.mileage = mileage
def description(self):
return f"The {self.name} car gives the mileage of {self.mileage}km/l"
class BMW(Car): #子类
pass
class Audi(Car): #子类
def audi_desc(self):
return "This is the description method of class Audi."
obj1 = BMW("BMW 7-series",39.53)
print(obj1.description())
obj2 = Audi("Audi A8 L",14)
print(obj2.description())
print(obj2.audi_desc())
咱们创立了两个子类,即“BMW”和“Audi”,它们继承了父类“Car”的办法和属性。在 BMW 类咱们没有提供额定的特色和函数。而 Audi 外部的一个附加办法。
留神在 obj1.description()和 obj2.description()的帮忙下,父类的实例办法 description()是如何被子类的对象拜访的。此外,还能够应用 obj2.Audi_desc()拜访 Audi 类的独自办法。
5. 封装
正如我在文章结尾局部提到的,封装是确保安全性的一种办法。基本上,它将数据暗藏起来,不让外人拜访。例如,如果咱们想让某些值不被客户或任何未经受权的人拜访,那么封装就是确保这一点的办法。
你能够在办法或属性的名称前应用一个下划线(_) 来申明受爱护的办法或属性。例如 self._name 或 def _method();这两行都阐明属性和办法是受爱护的,不应在类和子类的拜访之外应用,而是能够由类办法和对象拜访。
Python 只是将‘_‘用作编码约定,通知你应该在类的范畴内应用这些属性 / 办法。你依然能够像平常一样拜访定义为受爱护的变量和办法。
当初,为了理论避免从类范畴之外拜访属性 / 办法,能够应用“公有成员”。若要将属性 / 办法申明为公有成员,请在前缀中应用双下划线(__)。例如– self.__name 或 def __method();这两行都阐明属性和办法是公有的,不能从类内部进行拜访。
class car:
def __init__(self, name, mileage):
self._name = name #受爱护属性
self.mileage = mileage
def description(self):
return f"The {self._name} car gives the mileage of {self.mileage}km/l"
obj = car("BMW 7-series",39.53)
#通过类办法拜访受爱护变量
print(obj.description())
#间接从内部拜访受爱护变量
print(obj._name)
print(obj.mileage)
请留神咱们如何拜访受爱护的变量而没有任何谬误。很显著,对变量的拜访依然是公开的。让咱们看看封装是如何工作的
class Car:
def __init__(self, name, mileage):
self.__name = name #公有变量
self.mileage = mileage
def description(self):
return f"The {self.__name} car gives the mileage of {self.mileage}km/l"
obj = Car("BMW 7-series",39.53)
#通过类办法拜访公有变量
print(obj.description())
#间接从内部拜访公有变量
print(obj.mileage)
print(obj.__name)
当咱们尝试应用 description()办法拜访公有变量时,没有遇到任何谬误。然而当咱们尝试间接在类内部拜访公有变量时,Python 给出了一个谬误,申明:car 对象没有属性 ”__name’。
你依然能够应用该属性的润饰名称间接拜访它。Name mangling(命名润饰)是一种从内部拜访类成员的机制。Python 解释器将任何带有“__var”的标识符重写为“_ClassName__var”。应用这个你能够从内部拜访类成员。
class Car:
def __init__(self, name, mileage):
self.__name = name #公有变量
self.mileage = mileage
def description(self):
return f"The {self.__name} car gives the mileage of {self.mileage}km/l"
obj = Car("BMW 7-series",39.53)
#通过类办法拜访公有变量
print(obj.description())
#间接从内部拜访公有变量
print(obj.mileage)
print(obj._car__name) #名称润饰
请留神,这个规定的设计是想解决某些状况,例如在调试器中。然而失常编程中不举荐应用
6. 多态
多态 (Polymorphism) 一个希腊单词。如果咱们合成 Polymorphism 这一术语,咱们会失去“poly”(多)和“morph”(变形)模式。所以多态性意味着有多种形式。在 OOP 中,它指的是具备雷同名称但具备不同性能的函数。
class Audi:
def description(self):
print("This the description function of class AUDI.")
class BMW:
def description(self):
print("This the description function of class BMW.")
audi = Audi()
bmw = BMW()
for car in (audi,bmw):
car.description()
应用对象 audi 调用函数时,将调用 audi 类的函数;应用对象 bmw 调用函数时,将调用 bmw 类的函数。
7. 数据抽象
咱们应用形象来暗藏函数的外部细节或实现,只显示其性能。这与你在不晓得汽车原理的状况下晓得如何驾驶汽车,或者你晓得如何用开关关上或敞开灯,但你不晓得插座前面产生了什么的状况相似。
任何具备至多一个形象函数的类都是抽象类。为了首先创立一个抽象类,你须要从 ABC 模块导入 ABC 类。这使你能够在其中创立形象办法。ABC 代表形象基类。
from abc import ABC
class abs_class(ABC):
Body of the class
重要的是,不能为抽象类创立实例对象。例如 -
from abc import ABC, abstractmethod
class Car(ABC):
def __init__(self,name):
self.name = name
@abstractmethod
def price(self,x):
pass
obj = Car("Honda City")
当初的问题是咱们如何精确地应用这个形象。答案是应用继承。
from abc import ABC, abstractmethod
class Car(ABC):
def __init__(self,name):
self.name = name
def description(self):
print("This the description function of class car.")
@abstractmethod
def price(self,x):
pass
class new(Car):
def price(self,x):
print(f"The {self.name}'s price is {x} lakhs.")
obj = new("Honda City")
obj.description()
obj.price(25)
Car 是从 ABC 模块的 ABC 类继承的抽象类。留神我在抽象类中有一个形象办法 (price()) 和一个具体方法 (description())。这是因为抽象类能够同时蕴含这两种类型的函数,而一般类则不能。从这个抽象类继承的另一个类是 new。new 的 price() 办法是咱们重写了抽象类 Car 的 price 办法。
在用户从 new()类创建对象并调用 price()办法之后,new()类中 price 办法的定义就开始发挥作用了。这些定义对用户是暗藏的。形象办法只是提供一个申明。须要提供子类的定义。
然而,当为 new()类 (即 obj) 的对象调用 description()办法时,将调用 Car 的 description()办法,因为它不是形象办法。
结尾
总之,在本文中,我介绍了 Python 中面向对象编程的基本概念。当初你们晓得 OOPs 和基本概念了。
原文链接:https://www.analyticsvidhya.c…
欢送关注磐创 AI 博客站:
http://panchuang.net/
sklearn 机器学习中文官网文档:
http://sklearn123.com/
欢送关注磐创博客资源汇总站:
http://docs.panchuang.net/