​本篇可乐和大家一起来吃透 Python 的面向对象,类和实例。

面向对象(OOP)

解释:面向对象它是一种编程的思想,将现实事物抽象化为编程对象。

举例说明:喝可乐

① 选择自己根据配方买对应的材料然后制作可乐,最后喝可乐。

② 自己去小卖部直接买可乐喝。

第一种属于面向过程(对应到编程当中,也就是每一个步骤都需要一步一步实现)

第二种就是面向对象,我们并不需要知道每一步是如何实现的,只需要知道最后能够喝可乐即可。

一、类

解释:类是面向对象的重要组成部分,类是对相同特征和行为事物的统称,是一个抽象的概念。

语法

class 类名:

实际代码

举例:以人为例子

# 人有眼睛,鼻子,嘴巴这些特征。可以玩电脑,走路这些行为。
# 代码如下:
class Person:
def __init__(self):
self.eyes = "眼睛"
self.nose = "鼻子"
self.mouth = "嘴巴"

def play_computer(self):
print("我会玩电脑")

def walk(self):
print("我会走路")

# self:下面会细讲,并用代码演示

二、对象

解释:对象是类创建出来真实存在的事物,对象又可以称为实例。

语法

对象名 = 类名()

举例:以上述人为例子

人是一个抽象的概念,并不能代表实实在在的事物,但是可乐和在座的各位同学都是实际存在的事物,我们都属于人。

class Person:
def __init__(self):
self.eyes = "眼睛"
self.nose = "鼻子"
self.mouth = "嘴巴"

def play_computer(self):
print("我会玩电脑")

def walk(self):
print("我会走路") # 创建 kele 对象
kele = Person()

2.1 调用对象方法

语法

对象.方法名(参数)

​ 举例

class Person:
def __init__(self):
self.eyes = "眼睛"
self.nose = "鼻子"
self.mouth = "嘴巴"

def play_computer(self):
print("我会玩电脑")

def walk(self):
print("我会走路")

# 创建 kele 对象
kele = Person()
kele.play_computer()

# 输出 我会玩电脑

解释实例方法中的 self 是什么

先上代码

class Person:
def __init__(self):
self.eyes = "眼睛"
self.nose = "鼻子"
self.mouth = "嘴巴"

def play_computer(self):
print("我会玩电脑")

def eye(self):
print(self.eyes)
self.eyes = "卡兹然大眼睛"
print(self.eyes)


kele = Person()
kele.eye()

# 输出结果是 眼睛 卡兹然大眼睛


class Person:
def __init__(self):
self.eyes = "眼睛"
self.nose = "鼻子"
self.mouth = "嘴巴"

def play_computer(self):
print("我会玩电脑")

def eye(self):
pass


kele = Person()
print(kele.eyes)
kele.eyes = "卡兹然大眼睛"
print(kele.eyes)

# 输出 眼睛 卡兹然大眼睛

到这里可能有一部分同学已经明白 self 实际上是个什么东东了,为了更加通俗易懂,可乐再举一个例子:

class Person:
def __init__(self):
self.eyes = "眼睛"
self.nose = "鼻子"
self.mouth = "嘴巴"

def play_computer(self):
print(f"self是{self}")

kele = Person()
kele.play_computer()
print(f"kele是{kele}")

结果:



根据上述两个示例,我们可以知道 self 实际上就是类创建出来的实例对象。

对象在调用方法的时候不需要手动传 self 值,因为 python 解释器会自动将实例引用传递给 self 。

2.2 获取对象属性

解释:属性就是特征。例如:人的手,人的鼻子,人的身高,人的体重。

语法

① 对象名.属性名 (这种在类外部使用)

② self.属性名 (这种在类内部使用)

举例1:还是以人为例子

class Person:
def __init__(self):
self.eyes = "眼睛"
self.nose = "鼻子"
self.mouth = "嘴巴"

def play_computer(self):
print(f"self是{self}")


kele = Person()
print(kele.nose)

# 输出 鼻子

举例2

class Person:
def __init__(self):
self.eyes = "眼睛"
self.nose = "鼻子"
self.mouth = "嘴巴"

def get_nose(self):
print(self.nose)


kele = Person()
kele.get_nose()

# 输出 鼻子

2.3 修改/设置对象属性

语法

① 对象名.属性名 = 值 (这种在类外部使用)

② self.属性名 = 值 (这种在类内部使用)

举例1:依旧以人为例子

class Person:
def __init__(self):
self.eyes = "眼睛"
self.nose = "鼻子"
self.mouth = "嘴巴"

def play_computer(self):
print(f"self是{self}")


kele = Person()
kele.nose = "卡兹然大鼻子"
print(kele.nose)

# 输出 卡兹然大鼻子

举例2

class Person:
def __init__(self):
self.eyes = "眼睛"
self.nose = "鼻子"
self.mouth = "嘴巴"

def modify_nose(self):
self.nose = "卡兹然大鼻子"


kele = Person()
kele.modify_nose()
print(kele.nose)

# 输出 卡兹然大鼻子

2.4 魔法方法

解释:所谓的魔法方法也就是 python 内部已经提供的方法,他们的表现形式是 xxx 。

2.4.1 魔法方法 init

解释 init 方法它是用于对象生成之后进行初始化的函数,不需要程序员手动调用,python 解释器会在对象创建之后自动调用。

例如:人与生俱来就有嘴巴,鼻子,眼睛。那么我们在构造类的时候,就可以将这些属性放进 init 方法中。

举例

class Person:
def __init__(self):
self.eyes = "眼睛"
self.nose = "鼻子"
self.mouth = "嘴巴"
print(self.eyes)


kele = Person()

# 输出 眼睛

他并不需要程序员手动调用。

2.4.2 魔法方法 new

解释:我们之前一直在说对象是由类创建出来的,那么类又是怎么创建出来的呢?就是通过 new 方法,这个方法的功能就是创建对象。

如何通过 new 方法实现单例

解释:所谓的单例就是一个类创建出来的对象都是相同的。

在默认情况下类创建出来的各个对象都是不一样的,如果我们想一个类创建出来的对象都是一样的,那该怎么做呢?答案就是通过 new 方法。

类创建不同的对象代码

class Person:
def __init__(self):
self.eyes = "眼睛"
self.nose = "鼻子"
self.mouth = "嘴巴"


kele1 = Person()
kele2 = Person()
print(kele1)
print(kele2)

结果如图:



单例代码

class Person:
instance = None

def __new__(cls, *args, **kwargs):
if not cls.instance:
cls.instance = super(Person, cls).__new__(cls, *args, **kwargs)
return cls.instance

def __init__(self):
self.eyes = "眼睛"
self.nose = "鼻子"
self.mouth = "嘴巴"


kele1 = Person()
kele2 = Person()
print(kele1)
print(kele2)

先贴出结果:



解释一下代码:

具体代码在下面讲解完继承,类属性,类方法之后就知道什么含义了,可乐先讲一下代码的大致意思:用变量 instance 存储对象的内存地址,开始时只为 None ,当第一个对象创建之后,将该内存地址赋值给 instance 变量,后续的对象创建时判断变量 instance 是否有值了。如果有,那么将之前的对象地址给新对象。这样就保证了,后续的对象都和第一个对象的内存地址一样,即该类创建出来的对象都是同一个。

2.5 类属性

解释:类对象所拥有的属性,该类创建出来的所有对象共享同一个类属性,类属性在内存中只会有一个副本。

使用场景

如果在一个类中所有的对象都有一个共同的属性,并且这个属性的值是一样的,那么我们就可以将属性设置为类属性,如果这个属性的值每个对象都有其自己的含义,那么我们可以将其定义为实例属性。

语法

在类里面 属性名 = 值

举例

class Person:
nose = "鼻子"

def __init__(self, name):
self.name = name


kele1 = Person("可乐1号")
kele2 = Person("可乐2号")

2.5.1 获取类属性

语法

① cls.属性名 (在类里面)

② 类.属性名 (在类外面)

③ 实例.属性名 (在类外面)

举例

class Person:
nose = "鼻子"

kele = Person()

print(kele.nose)
print(Person.nose)

# 输出 鼻子 鼻子

2.5.2 修改类属性的值

语法

① cls.属性名 = 值 (在类里面)

② 类.属性名 = 值 (在类外面)

不可用实例.属性名 = 值来修改,这个含义代表添加实例属性。

举例

class Person:
nose = "鼻子"

Person.nose = "卡自然大鼻子"
print(Person.nose)

# 输出 卡自然大鼻子

2.6 类方法

解释:类方法是类对象所拥有的方法,用 @classmethod 来对方法进行修饰。

使用场景

类方法一般搭配类属性来使用,常常用于对类属性的修改。

语法

@classmethod

def 类方法名(cls):

举例

class Person:
nose = "鼻子"

@classmethod
def add(cls):
pass

2.6.1 调用类方法

语法

① 类.类方法名 (在类外面)

② 实例.类方法名 (在类外面)

③ cls.类方法名 (在类里面)

举例1

class Person:
nose = "鼻子"

@classmethod
def add(cls, nose):
cls.nose = nose

@classmethod
def update(cls):
cls.add("卡自然大鼻子")


Person.update()
print(Person.nose)

# 输出 卡自然大鼻子

举例2

class Person:
nose = "鼻子"

@classmethod
def update(cls):
cls.nose = "卡自然大鼻子"


Person.update()
print(Person.nose)

# 输出 卡自然大鼻子

举例3

class Person:
nose = "鼻子"

@classmethod
def update(cls):
cls.nose = "卡自然大鼻子"

kele = Person()
kele.update()
print(kele.nose)

# 输出 卡自然大鼻子

2.7 静态方法

解释:静态方法可以理解为就是普通的函数,只不过他的作用域限制于类里面,但是和类和实例本身并没有多大的关系,他通过 @staticmethod 来修饰。

使用场景

如果想定义一个函数,但是该函数和类本身或者实例对象没有多大关系,但是限制于该类中就可以使用静态方法来定义。

举例

class Person:
@staticmethod
def play_game():
print("可乐打游戏")

kele = Person()
kele.play_game()

# 输出 可乐打游戏

三、面向对象三大特性

特性:封装,继承,多态。

3.1 封装

解释:将代码写到类里面即是封装,并且封装还可以给属性或者方法设置权限。在上述代码中已经使用了封装的特性。

3.2 继承

解释:指的是类当中的从属关系,子类自动拥有父类所有的属性和方法。

所有的类都默认继承Object类。

3.2.1 单继承

单继承:只继承一个父类。

举例

class Father:

def __init__(self):
self.name = "可乐家族"

def get_name(self):
print(self.name)


class Son(Father):
pass


son = Son()
son.get_name()

# 输出 可乐家族

3.2.2 多继承

多继承:子类同时继承多个父类。

举例1

class Father:

def __init__(self):
self.name = "可乐家族"

def get_name(self):
print(self.name)


class Mother:

def __init__(self):
self.name = "妈妈家族"

def get_name(self):
print(self.name)

def add_nose(self):
self.nose = "鼻子"


class Son(Mother, Father):
pass


son = Son()
son.get_name()

# 输出 妈妈家族

举例2

class Father:

def __init__(self):
self.name = "可乐家族"

def get_name(self):
print(self.name)


class Mother:

def __init__(self):
self.name = "妈妈家族"

def get_name(self):
print(self.name)

def add_nose(self):
self.nose = "鼻子"


class Son(Father, Mother):
pass


son = Son()
son.get_name()

# 输出 可乐家族

如果继承的父类当中拥有相同的属性或者方法,那么优先继承第一个父类的属性和方法。

3.2.3 mro确认继承顺序

继承顺序:如果一个类继承多个父类,并且继承关系比较复杂,那么我们可以使用内置方法 mro 来确定继承顺序。

举例

class Father:

def __init__(self):
self.name = "可乐家族"

def get_name(self):
print(self.name)


class Mother:

def __init__(self):
self.name = "妈妈家族"

def get_name(self):
print(self.name)

def add_nose(self):
self.nose = "鼻子"


class Son(Mother, Father):
pass


print(Son.__mro__)

结果如图:

3.2.4 重写父类的方法

继承中,支持子类对父类的方法进行重写。

举例

class Father:

def __init__(self):
self.name = "可乐家族"

def get_name(self):
print(self.name)


class Mother:

def __init__(self):
self.name = "妈妈家族"

def get_name(self):
print(self.name)

def add_nose(self):
self.nose = "鼻子"


class Son(Mother, Father):

def get_name(self):
print("子类重新方法")


son = Son()
son.get_name()

# 输出 子类重新方法

3.2.5 继承之super

super:子类重写父类方法,但是还需要调用父类的其他方法或同名方法时,使用 super 可以不用关心继承的是哪个父类,在语法上只需要填写子类类名即可。

举例1

class Father:

def __init__(self):
self.name = "可乐家族"

def get_name(self):
print(self.name)


class Mother:

def __init__(self):
self.name = "妈妈家族"

def get_name(self):
print(self.name)

def add_nose(self):
self.nose = "鼻子"


class Son(Mother, Father):

def get_name(self):
print("子类重新方法")
Mother.get_name(self)
Father.__init__(self)
Father.get_name(self)


son = Son()
son.get_name()

# 输出 子类重新方法 妈妈家族 可乐家族

举例2

class Father:

def __init__(self):
self.name = "可乐家族"

def get_name(self):
print(self.name)


class Mother:

def __init__(self):
self.name = "妈妈家族"

def get_name(self):
print(self.name)
super(Mother, self).__init__()
super(Mother, self).get_name()

def add_nose(self):
self.nose = "鼻子"


class Son(Mother, Father):

def get_name(self):
print("子类重新方法")
super(Son, self).get_name()


son = Son()
son.get_name()

# 输出 子类重新方法 妈妈家族 可乐家族

super 会自动查找父类,且顺序遵循__mro__顺序,适合单继承使用;

super 只能继承最近的上一级父类,顺序按照__mro__顺序。

3.3 多态

解释:不同的对象,有不同的结果,子类重写父类的方法,并且调用不同的子类的相同父类方法,有不同的结果。

我们先上代码来看:

class Person:

def get_sex(self):
print("人")


class Man(Person):

def get_sex(self):
print("男人")


class Women(Person):

def get_sex(self):
print("女人")


man = Man()
women = Women()
man.get_sex()
women.get_sex()

# 输出 男人 女人

代码解释:

一个 Person 类中有一个父类公共方法 get_sex ,子类 man 和 women 通过重写父类方法,产生不同的效果,这就是多态。那么多态有什么好处呢?多态可以使得代码变得更加灵活,更通用,适应的业务场景多。

到此,我们在本篇中学习了 python 面向对象。各位同学在学习过程中遇到疑问可以私聊可乐,可乐看到了都会一一回复的。那么下一篇可乐将和大家看一下闭包,装饰器和深拷贝,浅拷贝。谢谢大家的支持~~~

< END>

如何吃透Python的面向对象(OOP)的更多相关文章

  1. [Python_4] Python 面向对象(OOP)

    0. 说明 Python 面向对象(OOP) 笔记.迭代磁盘文件.析构函数.内置方法.多重继承.异常处理 参考 Python面向对象 1. 面向对象 # -*-coding:utf-8-*- &quo ...

  2. python基础----面向对象的程序设计(五个阶段、对小白的忠告、关于OOP常用术语)、类、对象

    一.面向对象的软件开发有如下几个阶段                                              1.面向对象分析(object oriented analysis ,O ...

  3. Python面向对象OOP

    一 OOP     与C++和Java一样,Python同样具有OOP设计. 过程式:从前到后,一条一条,机器能接受的顺序性方式:方式大概为"首先你应该做什么,第二应该做什么,高级点的做点假 ...

  4. python基础——面向对象编程

    python基础——面向对象编程 面向对象编程——Object Oriented Programming,简称OOP,是一种程序设计思想.OOP把对象作为程序的基本单元,一个对象包含了数据和操作数据的 ...

  5. python学习------面向对象的程序设计

    一 面向对象的程序设计的由来 1940年以前:面向机器 最早的程序设计都是采用机器语言来编写的,直接使用二进制码来表示机器能够识别和执行的指令和数 据.简单来说,就是直接编写 和 的序列来代表程序语言 ...

  6. 【转】Python之面向对象与类

    [转]Python之面向对象与类 本节内容 面向对象的概念 类的封装 类的继承 类的多态 静态方法.类方法 和 属性方法 类的特殊成员方法 继承层级关系中子类的实例对象对属性的查找顺序问题 一.面向对 ...

  7. what's the python之面向对象

    编程分为面向过程和面向对象,首先我们要了解什么是面向对象. 面向对象 面向过程就是我们之前学的内容,主要是函数式,其核心是过程,过程即解决问题的步骤,面向过程的设计就好比精心设计好一条流水线,考虑周全 ...

  8. Python之面向对象类和对象

    Python之面向对象类和对象 定义一个类:class 定义类的语法: class Test(object): """ 类里定义一类事物共同的技能. 可以是变量,也可是函 ...

  9. python初始面向对象

    阅读目录 楔子 面向过程vs面向对象 初识面向对象 类的相关知识 对象的相关知识 对象之间的交互 类命名空间与对象.实例的命名空间 类的组合用法 初识面向对象小结 面向对象的三大特性 继承 多态 封装 ...

随机推荐

  1. 力扣643.子数组最大平均数I-C语言实现

    题目 给定 n 个整数,找出平均数最大且长度为 k 的连续子数组,并输出该最大平均数. 示例: 输入:[1,12,-5,-6,50,3], k = 4 输出:12.75 解释:最大平均数 (12-5- ...

  2. Python Line Messaging Api

    Line Messaging line 是国外一个很火的实时通信软件,类似与WX,由于公司业务需求,需要基于line开发一个聊天平台,下面主要介绍关于line messaging api 的使用. 官 ...

  3. 梨子带你刷burp练兵场(burp Academy) - 服务器篇 - Sql注入 - SQL injection UNION attack, determining the number of columns returned by the query

    目录 SQL injection UNION attack, determining the number of columns returned by the query SQL injection ...

  4. HDU 4628 Pieces(状压DP)题解

    题意:n个字母,每次可以删掉一组非连续回文,问你最少删几次 思路:把所有回文找出来,然后状压DP 代码: #include<set> #include<map> #includ ...

  5. u-boot 移植 --->7、u-bootl流程粗线条梳理

    通过前面的调试了解到s5pv210这个芯片的启动流程是需要将u-boot分为两部分的分别为SPL和u-boot.这里我使用网上的方式不直接使用u-boot的SPL连接脚本单独生成SPL的image而是 ...

  6. ES6 Arrow Function All In One

    ES6 Arrow Function All In One this const log = console.log; const arrow_func = (args) => log(`arg ...

  7. js & regex & var & highlight

    js & regex & var & highlight let key = `ali`.toLocaleUpperCase(); let name = "阿里云计算 ...

  8. Typescript All In One

    Typescript All In One TypeScript 3.5 is now available. https://www.typescriptlang.org/#download-link ...

  9. classnames & React & taro

    classnames & React & taro classnames https://www.npmjs.com/package/classnames demo https://g ...

  10. Bootstrap5 多级dropdown

    <div class="dropdown"> <a class="btn dropdown-toggle"> Dropdown link ...