10. 比找女朋友还难的技术点,Python 面向对象

梦想橡皮擦 等级 377 0 0

有人整个 Python 学习生涯都没有搞明白的技术之一:面向对象。

先放美图调整下心情。 10. 比找女朋友还难的技术点,Python 面向对象

十、Python 面向对象的编程

Python 准确的说也是一门面向对象编程的语言,简称 OOP,咱已经知道在 Python 中所有的数据类型都是对象,除了 Python 设置好的以外,Python 允许程序开发者自己定义数据类型,这种由程序员自定的数据类型就是

面向对象初学有门槛,学习请谨慎。

10.1 类的定义与使用

类的定义语法格式如下:

class MyClass():
    代码块
    ...
    代码块

类名的第一个字母建议大写,例如语法格式中的 MyClass

10.1.1 定义类、属性与方法

类的内部包含属性与方法,接下来咱定义一个 “人” 类。

# 定义人类
class Person():
    # 类的属性
    name = "橡皮擦"
    # 类的方法
    def talk(self):
        print("say hello")

在上述代码中,Person 是类名称,在这个类中定义了一个属性与一个方法。类的内部定义方法与函数非常相似,但是注意在类内部定义的函数可不能在称为函数了(是不是开始绕了),要叫做方法,因为只有类的对象才可以调用该方法。 方法定义时注意有一个参数为 self,牢记为固定写法,在所有类内部的方法参数中,都要写上 self 这个关键字。

10.1.2 属性与方法的调用

在调用属性与方法之前,必须先定义一个类的对象,具体方式如下,这个操作也叫做 实例化,类的实例化操作之后就出现了对象。

对象 = 类名()

例如刚才已经定义好了一个人类,使用下述代码可以获取一个人类的对象。

# 定义对象
xiang = Person()

对象定义完毕就可以使用属性与方法了。

class Person():
    # 类的属性
    name = "橡皮擦"

    # 类的方法
    def talk(self):
        print("say hello")

xiang = Person()
# 输出对象
print(xiang)

# 输出对象的属性
print(xiang.name)
# 输出对象的方法
xiang.talk()

代码运行之后,输出如下内容。

<__main__.Person object at 0x000002465F364B70>
橡皮擦
say hello

代码中的变量 xiang 就是 Person 类的一个对象,通过 xiang 对象可以读取 Person 类内的 name 属性与 talk 方法。

如果类还有其它的属性与方法,使用相同的方式即可实现。

10.1.3 类的构造函数

难度上在调高一点,建立类的同时希望初始一些数据进去,也就是初始化类,该内容是在类的内部编写一个方法,这个方法是一个特殊的方法,在编程的过程中定义类的对象将自动执行这个方法。

初始化方法名称是固定的 __init__,该方法在 init 左右各有两个下划线。类的初始化方法称为 构造函数(刚说了类里面叫做方法,自己就叫函数了,是不是迷糊了,这个还真没办法,大家都这么叫)。

接下来编写一个代码,当定义一个类的对象时候,默认给 Person 类的属性 name 赋值。

class Person():

    # 类的属性
    name = "橡皮擦"

    # 构造函数
    def __init__(self, in_name):
        self.name = in_name

    # 类的方法
    def talk(self):
        print("say hello")


xiang = Person('teacher')
# 输出对象
print(xiang)

# 输出对象的属性
print(xiang.name)
# 输出对象的方法
xiang.talk()

上述代码做了一些简单的变动,首先加入了 __init__ 构造函数,注意构造函数的参数有两个,一个是 self,这个在类内部定义函数的时候是必须的,并且需要放在参数的最左边,Python 在定义一个类的对象的时候会自动传入这个参数 selfself 代表的类本身的对象。

构造函数中还有一个参数 in_name,如果设计了构造函数,并且有除了 self 以外的其它参数,那在定义 Person 对象的时候,必须传递该参数,传递进来的该参数通过 self.name 可以修改对象的属性。

说起来很绕,简单里面就是每次当我们用类定义一个对象的时候,例如下述代码:

obj1 = Person()
obj2 = Person()

上面定义了两个对象,都是依据类 Person 定义的,self 这个参数在类的内部就表示具体是哪个对象。

如果还不理解,没有问题,记住下面的话。

类声明之后,相当于你自己定义了一个数据类型,你可以使用该种数据类型的变量,只是由于面向对象的概念,把这个变量叫做对象了,对象可以调用类的属性和方法,一个类对应多个对象,那如何判断具体是哪个对象在调用类内部的属性或者方法呢,需要用到的就是 self 这个参数。

10.1.4 属性初始值

在本部分之前,在类内部设定一个初始值,直接用 name = "橡皮擦" 来完成了,学习完构造函数之后,你应该了解到通常在 Python 初始化数据时,一般放在 __init__ 方法内。

class Person():

    # 构造函数
    def __init__(self, in_name, in_age):
        # 属性的初始化
        self.name = in_name
        self.age = in_age

    # 类的方法
    def talk(self):
        # 类中的属性,在初始化之后可以通过 self.name 调用
        print(self.name)
        print("say hello")

    def show_age(self):
        # 通过 self.age 调用初始化的年龄
        print(self.age)

xiang = Person('teacher', 19)
# 输出对象
print(xiang)

# 输出对象的属性
print(xiang.name)
# 输出对象的方法
xiang.talk()

10.2 封装

接下来要学习的是面向对象的三个基本特征之一,封装。

封装简单理解就行,先不要钻进去,理解概念,理解概念。

刚才我们使用的属性与方法都可以通过对象在类的外部访问,这些叫做公有属性与公有方法,但有些时候类内部的属性和方法不希望被外部对象进行修改,需要引入私有属性与私有方法相关概念,这种概念的引入导致了封装概念的出现。

封装就是封住类内部的东西,不叫你随便用(其实是有办法可以调用到的)。

10.2.1 私有属性

在类内部定义私有属性非常简单,是写作上的技巧,只需要在属性前面加上两个下划线即可,即 __name

例如在人类中定义一个秘密变量为私有属性。

class Person():
    # 构造函数
    def __init__(self, in_name, in_age):
        # 属性的初始化
        self.name = in_name
        self.age = in_age
        self.__secret = "我有代码洁癖" # 私有属性

    # 类的方法
    def talk(self):
        # 类中的方法,可以访问到私有属性
        print(self.__secret)
        print("say hello")

    def show_age(self):
        print(self.age)

xiang = Person('teacher', 19)

# 尝试输出对象的私有属性
print(xiang.__secret)  # 报错

# 尝试通过类的方法输出私有属性
xiang.talk()

类的内部初始化好私有属性之后,通过对象.属性名发现无法调用到私有属性,但是在类的内部是可以使用私有属性的,这种操作就叫做封装属性。

10.2.2 私有方法

有私有属性,必然有私有方法,这两个形式一样的,在方法前面加上两个下划线,就是私有方法了。

class Person():
    # 构造函数
    def __init__(self, in_name, in_age):
        # 属性的初始化
        self.name = in_name
        self.age = in_age
        self.__secret = "我有代码洁癖" # 私有属性

    # 类的方法
    def talk(self):
        # 类中的方法,可以访问到私有属性
        print(self.__secret)
        print("say hello")
    # 类的私有方法
    def __show_age(self):
        print(self.age)

xiang = Person('teacher', 19)

# 尝试输出对象的私有属性
# print(xiang.__secret)  # 报错

# 尝试通过类的方法输出私有属性
xiang.__show_age() # 报错

注意报错的内容,能记住就记住,熟练的找到代码错误的前提就是你碰到的代码错误足够多。

10.3 继承

学习继承概念以前,有几个新词需要学习一下,首先类是可以继承的,其中被继承的类称为父类或者基类,继承的类称为子类或者衍生类。使用类继承最大的好处就是,父类实现的公有属性或者方法在子类中不用重新设计了。

该内容也是说起来迷糊,先看一下语法格式。

# 定义个父类
class BaseClassName():
    父类的代码块

class ChildClassName(BaseClassName):
    子类的代码块

继承类的时候,括号内放置父类的名称。

10.3.1 继承的简单应用

声明一个动物类,然后让狗类继承动物类。动物类有一个公有属性叫做 name,一个公有方法叫做 sleep

# 定义 Animal 类
class Animal():
    def __init__(self):
        self.name = "动物名称"

    def sleep(self):
        print("动物都会睡觉")

# Dog 类继承自 Animal 类
class Dog(Animal):
    pass

dog = Dog()
print(dog.name)
dog.sleep()

上述代码中的 Dog 类没有任何属性与方法,只是继承了 Animal 类,就拥有了 Animal 类的公有属性与公有方法。

该继承方式,子类无法直接读取父类的私有属性或者方法,也就是下述代码是错误的。

# 定义 Animal 类
class Animal():
    def __init__(self):
        self.name = "动物名称"
        self.__secret = "秘密"

    def sleep(self):
        print("动物都会睡觉")

# Dog 类继承自 Animal 类
class Dog(Animal):
    pass

dog = Dog()
print(dog.__secret)
dog.sleep()

10.3.2 子类与父类有相同名称的属性或方法

在程序编写的时候,子类也可以有自己的初始化方法,即 __init__ 方法,在这种情况下会出现子类中的属性名、方法名与父类相同的情况,此时请以子类中的属性值或方法为主。

# 定义 Animal 类
class Animal():
    def __init__(self):
        self.name = "动物名称"
        self.__secret = "秘密"

    def sleep(self):
        print("动物都会睡觉")

# Dog 类继承自 Animal 类
class Dog(Animal):
    def __init__(self):
        self.name = "狗"

    def sleep(self):
        print("狗会睡觉")

# 父类的对象
animal = Animal()
animal.sleep()

# 子类的对象
dog = Dog()
dog.sleep()

该内容如果扩展开来就是面向对象的三大特征的最后一个 -- 多态

10.3.3 子类用父类的方法

使用 super 函数可以在子类中调用父类的方法,具体代码如下:

# 定义 Animal 类
class Animal():
    def __init__(self, a_name):
        self.name = a_name
        self.__secret = "秘密"

    def sleep(self):
        print("动物都会睡觉")

    def show(self):
        print("现在传递进来的名称为" + self.name)

# Dog 类继承自 Animal 类
class Dog(Animal):
    def __init__(self, a_name):
        # 调用父类对象的普通方法
        # super().sleep()
        super().__init__("动物名称" + a_name)

# 父类的对象
animal = Animal("普通动物")
animal.show()

# 子类的对象
dog = Dog("大狗狗")
dog.show()

Dog 类的构造函数中通过 super().__init__("动物名称" + a_name) 修改了传递给父类的参数,此方案相当于通过 super 函数生成一个父类的对象,然后在调用父类的 __init__ 方法,实现对父类的初始化操作。

10.4 多态

多态简单理解是说父类与子类有相同方法,通过父类、子类创建出的对象调用相同的方法名出现不同的结果。更多时候多态是程序会根据对象自动去调用指定的方法,该内容具体代码实现如下: 首先定义一个函数,这个函数有一个参数即可。

def gogo(obj):
    obj.say()

该函数的参数可以为任意数据类型的对象,然后在定义两个类,这两个类中需都存在 say 方法。

class Dog():
    def say(self):
        print("汪汪汪")

class Cat():
    def say(self):
        print("喵喵喵")

# 该函数会通过传进的对象进行判断是调用哪个方法。
def gogo(obj):
    obj.say()

# 通过 Dog 定义一个对象
dog = Dog()
# 通过 Cat 定义一个对象
cat = Cat()
# 在 gogo 函数中传递 dog 对象
gogo(dog)
# 在 gogo 函数中传递 cat 对象
gogo(cat)

以上代码当传入函数体内部的对象更换时,输出的数据不同,这种编码的形式或者叫编码的设计思路就是多态的一种展示。

简单理解就是 同一方法因对象不同导致实现内容不同

10.5 多重继承

上文讲解的都是单一继承关系,在实际编码中很多时候会用到多重继承,就是一个类继承多个父类,语法结构如下:

class 子类名称(父类1,父类2,父类3...):
    类的代码块

该内容不再进行扩展开讲解,在多重继承的时候,记住一句话就行,写在前面的父类比写在后面的父类优先级要高,也就说如果父类中都出现了同一个方法,那子类优先选择前面的父类,即上面语法格式中的 父类1

10.6 对象的数据类型判断

使用 type 函数可以判断某对象的数据类型,例如下述代码:

class Dog():
    def say(self):
        print("汪汪汪")

class Cat():
    def say(self):
        print("喵喵喵")

# 通过 Dog 定义一个对象
dog = Dog()
# 通过 Cat 定义一个对象
cat = Cat()

print(type(dog))
print(type(cat))

输出内容为:

<class '__main__.Dog'>
<class '__main__.Cat'>

type 可以获取到对象的来源类。

10.7 isinstance 函数

isinstance 函数可以判断对象是否属于某一个类,语法格式如下:

isinstance(对象,类) # 如果对象是由类实例化而来,返回 True,否则返回 Flase

该函数可以判断出一个对象是否实例化自父类。

# 父类
class Animal():
    pass

# 子类
class Dog(Animal):
    def say(self):
        print("汪汪汪")

# 子类
class Cat(Animal):
    def say(self):
        print("喵喵喵")

# 通过 Dog 定义一个对象
dog = Dog()
# 通过 Cat 定义一个对象
cat = Cat()

print(isinstance(dog,Dog)) # True
print(isinstance(dog,Animal)) # True
print(isinstance(cat,Animal)) # True

10.8 特殊属性、方法

在之前的课程中,使用 dir 函数作用于某一对象,会得到如下内容。 10. 比找女朋友还难的技术点,Python 面向对象 该内容存在大量的 __XXXX__ 的内容,这些就是一个对象中特殊的属性与方法。

接下来列举几个。

__doc__ 获取文档字符串

如果一个类中声明了文档字符串,就是在类的开始用 """ 三引号定义了一些内容,例如下述代码:

class Animal():
    """"
    我是文档字符串,相当于一个类的说明部分,其实我有标准的格式
    橡皮擦在第一遍滚雪球的时候,就是不愿意写
    """
    pass

animal = Animal()
print(animal.__doc__)

__name__ 属性 这里留下一个思考题,就是自行查阅 __name__ 属性是干啥的,如果理解了,以后看到下面的代码不会问为什么。

if __name__ == '__main__':
    执行某些代码

特殊方法部分在第一遍滚雪球的时候,不用费力去学习了,段位还没到,学了和没学一样,如果觉得非学不可,恰好是一个求索知识的机会,这时的学习会事半功倍的。

想学习可以自行找资料,关键词为 __str__()__repr__()__iter__()

10.9 这篇博客的总结

面向对象,对于编程初学者来说,这个东西学了跟没学一样,你要坚信不只是你无法在第一遍学习的时候就完全掌握,橡皮擦老师一样的,跟橡皮擦老师一起学习的老前辈同学也是一样的,橡皮擦带过的学生也是一样的,大家都一样,99%的人都一样,坚持就对了,先知道在 Python 中也有类,也有对象就够了,时间是学习最大的利器,打卡,打卡,每天学那么一点点,3 个月后见。

最后一碗毒鸡汤

前女友和我分手有两个原因,一是我当时没什么钱,二是她猜到了我将来也不会有什么钱。 O(∩_∩)O 哈哈~

🍂🍂🍂🍂🍂🍂🍂


收藏
评论区

相关推荐

Python的环境搭建和下载
Python是一个跨平台、可移植的编程语言,因此可在windows、Linux和Mac OS X系统中安装使用。 安装完成后,你会得到Python解释器环境,可以通过终端输入python命令查看本地是否已经按照python以及python版本。这里有一点需要注意的是,如果没有将python的安装目录添加到环境变量中,会报错(python不是内部命令或外部命
4. 列表一学完,Python 会一半,滚雪球学 Python
滚雪球学 Python,目标就是让 Python 学起来之后,越滚越大。 四、列表一学完,Python 会一半 4.1 列表是个啥 列表,先记住英文为 list ,它是 Python 中一种可以动态添加删除内容的数据类型,由一系列的元素组成。直白点说列表是将多个变量组合在一起的那么一个容器。 很多文章会找一个与列表相似的编程概念,一般会说 P
10. 比找女朋友还难的技术点,Python 面向对象
有人整个 Python 学习生涯都没有搞明白的技术之一:面向对象。 先放美图调整下心情。 十、Python 面
15. Python 程序运行速度如何提高十倍?第一遍滚雪球学 Python 收工
本篇文章将给大家介绍 Python 多线程与多进程相关知识,学习完该知识点之后,你的 Python 程序将进入另一个高峰。 <center<font colorred缓解一下视疲劳</font</center 15. Python 程序运行速度如何提高十倍?第一遍滚雪球学 Python 收工(https://imghelloworld.oss
知乎从Python转为Go,是不是代表Go比Python好?
众所周知,知乎早在几年前就将推荐系统从 Python 转为了 Go。于是乎,一部分人就说 Go 比 Python 好,Go 和 Python 两大社区的相关开发人员为此也争论过不少,似乎,谁也没完全说服谁。 知乎从Python转为Go,是不是代表Go比Python好?我认为,各有优点,谁也取代不了谁,会长期共存! “由 Python 语言转向 Go 语言
Python编程基础(快速入门必看
Python编程基础一、Python语言基本语法 Python是一
python文件的第一行 #!/usr/bin/python3 是什么意思?
python文件的第一行代码通常在脚本语言的第一行会看到: !/usr/bin/env python或 !/usr/bin/python 首先要确定的一点是它不是注释。这两句话的目的都是指出你的python文件用什么可执行程序去运行它。1. !/usr/bin/python 是告诉操作系统执行这个脚本的时候,调用 /usr/bin 下的 python 解释
最好用的Python学习教程第一篇章
学习不打烊,充电加油只为遇到更好的自己。希望大家如果觉得好的话可以点赞,评论鼓励一下。 一、从这里学起?学Python你应该知道这些内容。 1.1 导语如何快速学会Python?这篇博客会告诉你如何从无到有,构建自己的知识框架,博客主励志打造最好用的Python基础教程。 1.2 为什么要学习Python 简单易学Python是一种代表简单主义思想的语言,
怎么学python,学习python的正确姿势
Python是一门相对来说比较简单的编程语言,自学是非常轻松的。首先得明白python有哪些发展方向 需要了解这个这门语言 而不是听说 这个高薪资 容易学习最好的学习状态就是出于兴趣 兴趣是最好的老师 当然对钱感兴趣也是可以的。一、人工智能二、大数据三、网络爬虫工程师四、Python web全栈工程师五、Python自动化运维六、Python自动化测试再来说
关于学习python的一点意见分享
Python适合初学者入门。Python作为一门叫做ABC语言的替代品。 Python提供了高效的高级数据结构,还能简单有效地面向对象编程。相比其他主流语言,有更好的可读性,上手相对容易。各种模块,免去了很多重复的工作,更快地写出东西。配置环境也不复杂,mac和linux内置了Python。自学python,最大的3个经验:.一本易懂,比较好的教程,从头到尾
python的学习难?你的方法不对罢了,看看我的。
1、选择Python版本对于使用python的人来说,python的版本就是我们的工作环境,因此,在学习之前需要考虑好学习哪个版本,python2和python3的版本不同,会存在一些差异,虽说不大,但直接学习python3 的话相对来说会好一点,而且跑一趟还能3相对来说对零基础的小白来说更加的友好,容易上手。2、学习Python基础知识Python 是一个
小白学习python该往哪方面走小白必看
整理了Python的7大就业方向,希望大家能找到适合自己的,然后学习下去,完成人生的目标。1、Web开发(Python后端)Python有很多优秀的Web开发框架,如Flask、Django、Bootstar等,可以帮助你快速搭建一个网站。当需要一个新功能时,用Python只需添加几行代码即可,这受到了很多初创型公司的一致欢迎。像知乎、豆瓣、小米这样的大厂,
全网最全python学习路线图,让学习不迷路
学习Python有一段时间了,最近也是在不断的整理Python相关的基础知识和学习一些新的知识,想来分享给大家。我刚开始接触Python时,和大多数初学者一样不知道从那里开始学习python,我也在网上找了许多python相关的资料来学习,但是资料多也不见得就好,因为不知道从哪里开始下手,走了许多弯路。后面我就整理了一套对初学者来说学习python能很快上手
Python 之父爆料:明年至少令 Python 提速 1 倍!
大概在半年前,我偶然看到一篇文章,有人提出了给 Python 提速 5 倍的计划,并在寻找经费赞助。当时并没有在意,此后也没有看到这方面的消息。 但是,就在 5 月 13 日“2021 年 Python 语言峰会”上,Python 之父 Guido van Rossum 作了一场《Making CPython Faster》的分享,他已经投入了这项计划!据
怎么操作能使Python代码运行起来速度飞快?
Python是开发人员当中流行的编程语言之一。它应用广泛,无论是Web开发还是机器学习。Python大受欢迎的原因有很多,比如社区支持、出色的库、广泛用于机器学习和大数据以及简单的语法。尽管有这么多优点,Python还是有一个缺点:速度慢。作为一种解释性语言,Python的速度不如其他编程语言。不过,我们可以用几个技巧来克服这个问题。本文将分享几个Pytho