Python 中的面向对象编程
面向对象编程(Object-oriented programming, OOP)是一种基于对象概念的编程范式,可包含属性(attribute)形式的数据以及方法(method)形式的代码。另一种对 OOP 的解释是构建来灵活的且可复用的模块或是库,就像 Numpy 和 Pandas。
Python 中的所有内容都是对象。就像字符串(string)和列表(list)都是 Python 中的对象。而类就是创建对象的蓝图。基于面向对象机制编写的代码易于维护,是因为它的模块化结构,同时程序也因为封装而更安全。
这篇教程讨论了面向对象编程中的类、对象、方法、多态和继承,以给你提供一个良好的面向对象编程的基础。
点击免费领取:全网最全python学习导图+14张思维导图,让你学习不走弯路!
类
Python 现有的数据结构中就像整型还有字符串,都被设计为代表类似员工编号、员工姓名之类的东西。OOP 中的类就像是对象的蓝图,你还可以设计你自己的数据结构。举个例子,你可以创建一个 Employee 类来展现员工姓名和薪水的属性。
关键字calss 用以创建一个类,后面紧跟类型与冒号,类的主体部分起一新行并且缩进一个制表符。构造函数constructor是当你创建对象时被默认调用的一个方法,你需要通过关键字init来创建构造函数。在下面的例子当中,我创建了一个 Employee 类,与两个(class attributes)类属性 status 与 number_of_employee,同时两个(instance attributes)实例属性 employee_id 与 name,还有一个 give_info() 方法。
class Employee:
#class attributes
status = "active"
number_of_employee =
def __init__(self, employee_id, name):
self.employee_id = employee_id #instance attribute
self.name = name #instance attribute
Employee.number_of_employee +=
#class method
def give_info(self):
print("Name:",self.name,"\nID:",self.employee_id)
在表达式
self.employee_id = employee_id
中第一个 employee_id 是一个(instance attributes)实例属性或称为变量,第二个 employee_id 是一个参数,变量 name 也是同样的道理。当你通过类创建一个对象的时候,你可以这样写,
emre = Employee("", "Emre Kutlug")
对象
如前所述,类是创建对象的蓝图。一个类和对象的关系可以理解为动物和瑜伽熊的关系;瑜伽熊是一种动物,动物是一个抽象的概念,它以瑜伽熊和米老鼠的形式来实现。因此我们要先创建一个对象的类后才能使用它的方法和属性。
对象也被称为实例。因此,创建一个类的对象的过程也被成为实例化(instantiation)。在 Python 中创建类的对象,你必须在类名后紧跟圆括号。
我还可以使用type方法来检查这个对象的类型。输入:
type(emre)
输出:
<class '__main__.Employee'>
你可以通过类的对象来访问类的(class attributes)类属性和(instance attributes)实例属性或者调用类的方法。为此,你必须写下对象名后跟点(.)操作符与你想访问的属性名或是方法名,看看下面的例子吧,输入:
>>> emre.status
'active'
>>> emre.number_of_employee >>> emre.employee_id
''
>>> emre.give_info()
Name: Bob
ID:
属性
你可以用内建函数dir()来查看一个对象的所有属性和方法。Python 中有很多的内建的属性与方法,下面的例子将会展示 emre 对象中的所有属性与方法,其中前面带有双下划线的都是内嵌的。
>>> dir(emre)
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'employee_id', 'give_info', 'name', 'number_of_employee', 'status']
>>>
两种类型的属性当中,(class attributes)类属性的值将贯穿全部的对象,而(instance attributes)实例属性的值会因对象的不同而不同。实例属性可以定义在任何方法当中,而类属性定义在方法之外。实例属性通过self关键字来引用,而类属性在方法中通过类名来引用。在下面的例子当中,我们先来看 number_of_employee 属性的值,再来创建一个同类的其他对象
>>> emre.number_of_employee
>>> emma = Employee("", "Emma Stone")
>>> emma.give_info()
Name: Emma Stone
ID:
>>>
当我们再在下面的例子当中输出 number_of_employee 的值的时候,将会是 2,因为这是类属性,两个对象都共享其值。
>>> emma.number_of_employee >>>
方法
前面提到过了,你可以用方法来实现对象的功能。之前我都是用一个类的对象来调用它的方法,但是还有另一种方法 —— 静态方法(static method),可以直接同过类名来调用。静态方法只能访问类属性,下面的例子当中,我将为 employee 类添加一个静态方法
class Employee:
#class attributes
status = "active"
number_of_employee =
def __init__(self, employee_id, name):
self.employee_id = employee_id #instance attribute
self.name = name #instance attribute
Employee.number_of_employee +=
#class method
def give_info(self):
print("Name:",self.name,"\nID:",self.employee_id)
@staticmethod
def get_class_objective():
message = "The objective of this Employee class is to organize employee information with more modular manner"
print (message)
输入:
>>> Employee.get_class_objective()
The objective of this Employee class is to organize employee information with more modular manner
>>>
全局变量与局部变量
类的属性也被称为是变量,变量又分为两种类型:局部变量和全局变量。类中的局部变量是在方法中定义的并只能再方法中访问到,因此你不能在 get_class_objective() 方法之外访问到 message 变量。当你试图访问的时候,将会得到 AttributError,
全局变量不被定义在任何方法当中,因此你可以在类种的任何地方访问到它们。之前例子当中的 status 与 number_of_employee 都是全局变量。
点击免费领取:全网最全python学习导图+14张思维导图,让你学习不走弯路!
封装
OOP 中有三个主要的概念:分装 Encapsulation、继承 Inheritance 与多态 Polymorphism。封装指的就是数据隐藏。OOP 中的一个类不应该直接就能访问到另一个类的数据,或者说数据的访问应该交由方法来控制着。你可以用私有变量和 property 来控制类数据的访问。在变量名前加上两个下划线便可定义私有变量,例如 __age 就是私有变量。
你可以为 age 属性创建一个 property 来符合这个逻辑,就像下面的代码一样。一个 property 有三个部分,你必须定义这个属性 —— 下例中为 age;接着你必须通过@property装饰器(decorator)来为属性定义 property;最后你必须创建一个 property setter,下例当中为 @age.setter 装饰器。你可以设定员工的年龄都必须在 19 到 99 岁之间,如果有人想给 age 属性设定超过其范围的值,将会引发报错并无法创建。
class Employee:
#class attributes
status = "active"
number_of_employee =
def __init__(self, employee_id, name, age):
self.employee_id = employee_id #instance attribute
self.name = name #instance attribute
self.age = age #instance attribute
Employee.number_of_employee +=
# Creates model property
@property
def age(self):
return self.__age
# Create property setter
@age.setter
def age(self, age):
if age < :
raise Exception('An Employee\'s age cannot be lower than 18')
elif age > :
raise Exception('An Employee\'s age cannot be upper than 99')
else:
self.__age = age
继承
OOP 中的继承就很像真实世界当中的孩子继承了他父母的一些特征,再加上自身独特的特征。继承了其他类的类被称为子类,被继承的类则为父类。就像下面这样
# Create Class Manager that inherits Employee
class Manager(Employee):
def set_team_size(self, team_size):
self.team_size = team_size
为了说明某类继承了一个类,你必须将其父类写在其类名后的圆括号之中。Manager 类可以访问到其父类 Employee 的全部属性与方法
>>> muge = Manager("", "Muge Ozkan", )
>>> muge.name
'Muge Ozkan'
>>> muge.status
'active'
>>> muge.get_class_objective()
The objective of this Employee class is to organize employee information with more modular manner
>>>
除了其父类的属性与方法之外,Manager 类还有他独有的 set_team_size() 方法,顺带一提,一个类可以有两个以上的父类或是子类。
多态
多态指的是一个对象可以有多种表现方式的能力,两种类型的多态分别是:方法重写和方法重载(method overriding and method overloading。)
方法重写
方法重写意味着在子类与父类当中有着同名方法,虽然其中的定义是不同的但他们都保留着相同的名字。如果你还记得我们在 Employee 类当中有一个 give_info() 的方法,我们便可以在 Manager 类当中进行重写,以显示经理类中的团大大小信息,
class Manager(Employee):
team_size =
def set_team_size(self, team_size):
self.team_size = team_size
def give_info(self):
print("Name:",self.name,"\nID:",self.employee_id,"\nTeam Size:",self.team_size)
接着
>>> muge = Manager("", "Muge Ozkan", )
>>> muge.give_info()
Name: Muge Ozkan
ID:
Team Size:
>>>
如你所见,当子类与父类都在调用同名方法时产生了不同的表现,是因为在子类中重写了父类的方法。
方法重载
你可以通过改变调用时参数的类型与个数来重载任何一个方法,这样这个方法将会有不同的表现。在下面的例子中,如果我们在调用 calculate_salary() 方法时只传一个参数,它将返回这个参数。然而如果我们传递两个参数,它将返回两数之和。
class Manager(Employee):
team_size =
def set_team_size(self, team_size):
self.team_size = team_size
def give_info(self):
print("Name:",self.name,"\nID:",self.employee_id,"\nTeam Size:",self.team_size)
def calculate_salary(self, salary, bonus=None):
if bonus is not None:
salary += bonus
return salary
接着
>>> muge = Manager("", "Muge Ozkan", )
>>> muge.calculate_salary()
>>> muge.calculate_salary(, )
>>>
结论
本篇教程介绍了面向对象编程中的类、对象、属性和方法的概念,接着是封装、继承和多态,他们都是面向对象编程中的核心。OOP 是最常用的编程范例之一,因此大多数现代的编程语言像 Python 都支持面向对象编程。
想了解更多关于python的干货知识,请扫码下方二维码哦!

Python 中的面向对象编程的更多相关文章
- python中的面向对象编程
在python中几乎可以完成C++里所有面向对象编程的元素. 继承:python支持多继承: class Derived(base1, base2, base3): pass 多态:python中的所 ...
- Python中的并发编程
简介 我们将一个正在运行的程序称为进程.每个进程都有它自己的系统状态,包含内存状态.打开文件列表.追踪指令执行情况的程序指针以及一个保存局部变量的调用栈.通常情况下,一个进程依照一个单序列控制流顺序执 ...
- Python:笔记(3)——面向对象编程
Python:笔记(3)——面向对象编程 类和面向对象编程 1.类的创建 说明:和Java不同的是,我们不需要显示的说明类的字段属性,并且可以在后面动态的添加. 2.构造函数 构造函数的功能毋庸置疑, ...
- Python学习之==>面向对象编程(二)
一.类的特殊成员 我们在Python学习之==>面向对象编程(一)中已经介绍过了构造方法和析构方法,构造方法是在实例化时自动执行的方法,而析构方法是在实例被销毁的时候被执行,Python类成员中 ...
- Python 中的 TK编程
可爱的 Python:Python 中的 TK编程 http://www.ibm.com/developerworks/cn/linux/sdk/python/charm-12/ python che ...
- 可爱的 Python : Python中的函数式编程,第三部分
英文原文:Charming Python: Functional programming in Python, Part 3,翻译:开源中国 摘要: 作者David Mertz在其文章<可爱的 ...
- 22.python中的面向对象和类的基本语法
当我发现要写python的面向对象的时候,我是踌躇满面,坐立不安呀.我一直在想:这个坑应该怎么爬?因为python中关于面向对象的内容很多,如果要讲透,最好是用面向对象的思想重新学一遍前面的内容.这个 ...
- Python中的多线程编程,线程安全与锁(二)
在我的上篇博文Python中的多线程编程,线程安全与锁(一)中,我们熟悉了多线程编程与线程安全相关重要概念, Threading.Lock实现互斥锁的简单示例,两种死锁(迭代死锁和互相等待死锁)情况及 ...
- Python中的并行编程速度
这里主要想记录下今天碰到的一个小知识点:Python中的并行编程速率如何? 我想把AutoTool做一个并行化改造,主要目的当然是想提高多任务的执行速度.第一反应就是想到用多线程执行不同模块任务,但是 ...
随机推荐
- Java 根据地图定位坐标推荐附近的目标地址(直线距离)
这两天需要在公众号上面做一个关于根据地图当前定位与目标地址直线距离远近推荐的查询,一开始摸不着头脑,现已解决,mark一下 现有的材料:当前用户手机端的通过微信定位的经纬度坐标.数据表中保存有场地的定 ...
- 一个JS库Lodash
中文文档:https://www.html.cn/doc/lodash/#_aftern-func
- Spring Boot 整合 Apollo
简介 Apollo(阿波罗)是携程框架部门研发的分布式配置中心,能够集中化管理应用不同环境.不同集群的配置,配置修改后能够实时推送到应用端,并且具备规范的权限.流程治理等特性,适用于微服务配置管理场景 ...
- 黎活明8天快速掌握android视频教程--20_采用ContentProvider对外共享数据
1.内容提供者是让当前的app的数据可以让其他应用访问,其他应该可以通过内容提供者访问当前app的数据库 contentProvider的主要目的是提供一个开发的接口,让其他的应该能够访问当前应用的数 ...
- 深入浅出腾讯BERT推理模型--TurboTransformers
Overview TurboTransformers是腾讯最近开源的BERT推理模型,它的特点就是一个字,快.本人用BERT(huggingface/transformers)在V100上做了测试,测 ...
- 使用迭代器模式批量获得数据(C#实现)
先说一下项目的背景,以前曾经做过一个项目,根据Excel中的数据批量的到网页上抓取数据,将抓取到的数据批量的回填到Excel中.这个Excel中有很多行的记录(多的时候会有好几千行),每一行数据存储能 ...
- Redis高级特性介绍以及实例分析
Redis基础类型回顾 转自:http://www.jianshu.com/p/af7043e6c8f9 String Redis中最基本,也是最简单的数据类型.注意,VALUE既可以是简单的Stri ...
- DOM-BOM-EVENT(4)
4.dom操作 createElement 创建一个元素 <button id="btn">点击</button> <ul id="ul1& ...
- pycham中报:ModuleNotFoundError: No module named 'pymysql'
参考https://www.cnblogs.com/wupeiqi/articles/5713330.html https://pypi.python.org/pypi # D:\Program Fi ...
- 新建maven项目总是需要重新选择maven的配置文件
解决办法: other settings->settings for new projects... 找到maven设置自己的目录和配置