Python中的魔力编程:掌握面向对象之道

Python中的面向对象编程

背景:

​ 最近在看一些代码的时候,对类中的一些内置方法不是很懂,因此出一篇文章来细说一下,希望大家看完后对Python中类有一个清楚的认识。

基础铺垫:

​ 面向对象的三个特点:封装、继承、多态。面向对象的好处无非就是增加代码的复用性,利于维护和修改,这也是高内聚,低耦合的体现。

  1. 封装
    • 封装是一种将数据(属性)和操作数据的方法(方法)封装在一个单元内的机制。
    • 类的成员变量可以设置为私有,只能通过类的方法来访问和修改。
  2. 继承
    • 继承允许你创建一个新类,该类继承了一个现有类的属性和方法。新类称为子类,原始类称为父类或基类。
    • 子类可以扩展或修改继承的属性和方法,也可以添加新的属性和方法。
  3. 多态
    • 多态性允许不同类的对象对相同的方法名做出不同的响应。这是通过方法的重写和接口的实现来实现的。
类的特性:

Python使用class关键字来定义类,其基本结构如下:

  • class 类名(): #一般类名首字母是大写
        pass
    
内置方法合集(重点):

​ 内置方法(也称为魔术方法或双下划线方法),它们具有特殊的含义和用途,为什么你有的时候看不懂一些方法,因为他是固定的,比较便捷,我们只需要对其重写即可。

  1. __init__(self, ...): 这是一个类的构造方法,用于初始化对象的属性。当你创建一个类的新实例时,__init__ 方法会自动调用,进行相关的赋值操作。
  2. __str__(self): 用于返回一个可读的对象字符串表示。当你使用 print 函数打印一个对象时,它会自动调用 __str__ 方法来获取字符串表示,我们一般对其重写。
  3. __repr__(self): 用于返回一个对象的官方字符串表示。通常,它应该返回一个字符串,以用于创建相同对象的副本。
  4. __len__(self): 这用于返回对象的长度。你可以通过内置函数 len() 来获取对象的长度,它会自动调用 __len__ 方法。
  5. __getitem__(self, key): 这用于允许对象像字典或列表一样通过索引或键来访问其元素。它用于实现对象的索引访问。
  6. __setitem__(self, key, value): 用于允许对象像字典或列表一样通过索引或键来设置其元素的值。它用于实现对象的索引赋值。
  7. __delitem__(self, key): 用于允许对象像字典或列表一样通过索引或键来删除其元素。它用于实现对象的索引删除。
class Book:
    # self 是调用者
    def __init__(self, title, author, pages): # Book类内置属性 标题 作者 页数
        self.title = title
        self.author = author
        self.pages = pages

    def __str__(self):
        return f"{self.title} by {self.author}"

    def __repr__(self):
        return f"Book({self.title}, {self.author}, {self.pages})"

    def __len__(self):
        return self.pages

    def __getitem__(self, page_number):
        if page_number >= 1 and page_number <= self.pages:
            return f"Page {page_number} of {self.title}"
        else:
            raise IndexError("Page number out of range")

    def __iter__(self):
        self.current_page = 1 # 封装一个属性
        return self

    def __next__(self):
        if self.current_page <= self.pages:
            result = f"Page {self.current_page} of {self.title}"
            self.current_page += 1
            return result
        else:
            raise StopIteration
# 创建一个Book对象
book = Book("Python Basics", "John Smith", 100) #会自动调用 __init__ 方法

# 使用内置方法
#  打印对象 会自动调用__str__
print(book) # 输出: Python Basics by John Smith 
# 调用__len__ 函数
print(len(book)) #输出 100
# 调用__repr__ 函数
print(repr(book))  # 输出: Book(Python Basics, John Smith, 100)
# __getitem__ 当取某一个元素得时候会自动调用
print(book[1])  # 输出: Page 1 of Python Basics
print(book[50])  # 输出: Page 50 of Python Basics

# # 迭代书的页面
for page in book:
    print(page)

#  第一次调用会执行__iter__函数,然后不断使用__next__ 函数,for page in book:会反复调用 __next__ 方法,每次迭代都会获取下一页的页面信息,直到没有更多的页面可供迭代为止。

在这里插入图片描述

组合:

组合指的是,在一个类中以另外一个类的对象作为数据属性,称为类的组合

class Student():
    def __init__(self):
        # 将创建好的手机对象赋值给了phone这个实例变量
        self.phone = Phone('霸王别姬')


class Phone():
    def __init__(self, movie_name):
        self.movie_name = movie_name

    def playMovie(self):
        print('手机正在播放的电影是:', self.movie_name)

s1 = Student()
s1.phone.playMovie()

在这里插入图片描述

继承:

​ 通过继承,你可以创建一个新类(子类),它可以继承另一个类(父类或基类)的属性和方法。子类可以扩展或修改父类的功能,并可以添加自己的属性和方法。

  1. 父类和子类
    • 父类是被继承的类,也被称为基类或超类。
    • 子类是继承父类的类,也被称为派生类。
  2. 继承语法
    • 在子类的类定义中,将父类作为子类的参数传递给类定义。
    • 使用 super() 函数可以在子类中调用父类的方法。
class ParentClass:
    def __init__(self, name):
        self.name = name

    def speak(self):
        print(f"{self.name} is speaking.")

class ChildClass(ParentClass):
    def __init__(self, name, age):
        super().__init__(name)  # 调用父类的构造方法
        self.age = age

    def speak(self):
        super().speak()  # 调用父类的方法
        print(f"{self.name} is {self.age} years old and speaking.")

child = ChildClass("Alice", 10)
child.speak()

在这里插入图片描述

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

class ChildClass(ParentClass):
    def __init__(self, name, age):
        # 不显式调用父类的构造方法,Python会自动调用
        self.age = age

child = ChildClass("Alice", 10)
print(child.name)  # 输出: Alice
print(child.age)   # 输出: 10

​ 子类 ChildClass 的构造方法没有显式调用 super().__init__(name),但仍然可以正确地初始化 name 属性,因为Python会自动调用父类 ParentClass 的构造方法。但是,如果你在子类的构造方法中想做一些其他特定于子类的初始化工作,你可以显式调用 super().__init__(name) 来确保父类的构造方法也被执行。

多态:
class Animal:
    def speak(self):
        pass

class Dog(Animal):
    def speak(self):
        return "Woof!"

class Cat(Animal):
    def speak(self):
        return "Meow!"

def make_animal_speak(animal):
    return animal.speak()

dog = Dog()
cat = Cat()

print(make_animal_speak(dog))  # 输出: "Woof!" 调用谁得对象,执行who得函数
print(make_animal_speak(cat))  # 输出: "Meow!"

实例变量和类变量:
实例变量:
  • 实例变量指的是实例化对象本身拥有的变量。
  • 通过实例名加圆点的方式调用实例变量 对象.属性
class Student():
    def __init__(self,i_name,i_age):
        #只要定义在init方法内部的变量就是【实例/对象变量】
        self.name = i_name #self.name就是定义的实例变量,name是init方法的参数值
        self.age = i_age #self.age就是定义的实例变量,age就是init方法的参数值

s1 = Student('xxx',21) #调用Student类中的init这个构造方法
s2 = Student('lisi',225)
print(s1.name,s1.age) #访问s1对象的name和age这两个实例变量
print(s2.name,s2.age) #访问s2对象的name和age这两个实例变量
类变量:

​ 顾名思义,类和实例化对象公用得属性叫做类变量。定义在类中,方法之外的变量,称作类变量。类变量是所有实例公有的变量,每一个实例都可以访问类变量。

class Student():
    # 定义在方法外部的变量:类变量
    address = 'Beijing'
    classroom = 167

    def __init__(self, i_name, i_age):
        # 只要定义在init方法内部的变量就是【实例/对象变量】
        self.name = i_name
        self.age = i_age


s1 = Student('zhangsan', 20)  # 调用Student类中的init这个构造方法
s2 = Student('lisi', 25)
# 根据对象的引用访问对象的实例变量
print(s1.name, s1.age)  # 访问s1对象的name和age这两个实例变量
print(s2.name, s2.age)  # 访问s2对象的name和age这两个实例变量
print(s1.address, s1.classroom) # 对象访问类变量
print(Student.address,Student.classroom) # 类访问类变量

一句话:类变量是可以被所有的对象公用的

类的方法:

​ Python的类中可以包含三种不同类型的方法:实例方法、静态方法和类方法。它们之间的区别主要涉及参数和调用方式,

实例方法
  • 实例方法是最常见的方法类型,在类内部定义时,第一个参数通常是 self,它表示对象自身。
  • 实例方法可以访问和修改对象的属性,因为它们有对当前实例的引用。
class Student():
    classroot = 167 #类变量
    #构造方法
    def __init__(self,name,age):
        #实例变量
        self.name = name
        self.age = age

    #注意:实例方法只可以通过对象调用。
    def study(self,book):
        print('正在学习的书籍是:',book)

s = Student('zhangsan',20) #实例化对象
#只给除了self其他的参数传值
s.study('C++程序设计')
静态方法
  • 静态方法在类内部定义时,使用 @staticmethod 装饰器来标识,它们不需要访问对象的状态,因此没有 self 参数。
  • 静态方法通常用于类级别的操作,而不是实例级别的操作。
class Obj():
    def __init__(self):
        pass

    # 定义一个静态方法
    @staticmethod
    def staticFunc(name):  # 静态方法不需要有任何的必要参数(self)
        print('我是静态方法!,我有一个普通参数:', name)


Obj.staticFunc('帅哥')  # 通过类名调用(推荐)
o = Obj()
o.staticFunc('小帅哥')  # 通过对象名调用(不推荐)

类方法
  • 类方法在类内部定义时,使用 @classmethod 装饰器来标识,它们的第一个参数通常是 cls,它表示类本身。
  • 类方法可以访问和修改类级别的属性,通常用于创建、操作或修改类级别的状态。
class Obj():
    f = 'classVar'  # 类变量

    def __init__(self):
        pass

    @classmethod
    def classFunc(cls):  # 类方法必须要有一个cls的参数,且作为第一个参数
        # cls也不是python的关键字,cls也可以写作其他的形式,比如:xx,self
        print('我是类方法!必要参数cls的值为:', cls)
        print('类变量的值为:', cls.f)  # 类名访问类变量



o = Obj()
o.classFunc()  # 通过对象名访问(不推荐)

Obj.classFunc()  # 通过类名访问(推荐)

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/237090.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【设计模式--结构型--享元模式】

设计模式--结构型--享元模式 享元模式定义结构实现案例优缺点使用场景 享元模式 定义 运用共享技术来有效的支持大量细粒度对象的复用。它通过共享已经存在的对象来大幅减少需要创建的对象数量&#xff0c;避免大量相似的对象的开销&#xff0c;从而提高系统资源的利用率。 …

创建并测试第一个django项目并解决过程中遇到的问题

Django 是一个高级 Python Web 框架&#xff0c;它鼓励快速开发和简洁、实用的设计。它由经验丰富的开发人员构建&#xff0c;解决了 Web 开发的大部分麻烦&#xff0c;因此您可以专注于编写应用程序&#xff0c;而无需重新发明轮子。它是免费和开源的。 目录 一、django项目 …

官宣!「湾区之光群星演唱会」拉开2024新年音乐华丽序幕!

万众期待&#xff0c;群星荟萃&#xff01;青春宝安时尚湾区——湾区之光群星演唱会即将在2024年1月5日闪耀亮相深圳宝安。 华语歌坛巨星天后齐聚一堂&#xff0c;携手多位实力唱将&#xff0c;共同呈现一场无与伦比的演唱会盛宴&#xff01;在深情而又充满力量的歌声之中&…

孩子还是有一颗网安梦——Bandit通关教程:Level 0 → Level 1

&#x1f575;️‍♂️ 专栏《解密游戏-Bandit》 &#x1f310; 游戏官网&#xff1a; Bandit游戏 &#x1f3ae; 游戏简介&#xff1a; Bandit游戏专为网络安全初学者设计&#xff0c;通过一系列级别挑战玩家&#xff0c;从Level0开始&#xff0c;逐步学习基础命令行和安全概念…

LabVIEW开发矿井排水监控系统

LabVIEW开发矿井排水监控系统 针对矿井水害对煤矿安全生产构成的威胁&#xff0c;设计了一种基于嵌入式PLC和LabVIEW的矿井排水监控系统。该系统结合了PLC的可靠控制与单片机的应用灵活性&#xff0c;有效克服了传统排水方法中的不足&#xff0c;如测量不准确、效率低下等问题…

Java:字符流 文件输出 与 读入 方法

Java&#xff1a;字节流 文件输出与读入方法 并 实现文件拷贝 文章目录 字符流FileReaderFileWrite 字符流 字符流底层就是字节流。 字符流 字节流 字符集 特点&#xff1a; 输入流&#xff1a;一次读入一个字节&#xff0c;遇到中文时&#xff0c;一次读多个字节。 输出流…

图-数据结构

图的介绍 如果你有学过《离散数学》&#xff0c;那么对图的概念一定不陌生&#xff0c;在计算机科学中&#xff0c;一个图就是一些顶点的集合&#xff0c;这些顶点通过一系列边连接&#xff08;结对&#xff09;。顶点用圆圈表示&#xff0c;边就是这些圆圈之间的连线。注意&a…

Design patterns--代理模式

设计模式之代理模式 我们使用Qt开发大型应用程序时&#xff0c;经常遇见大型程序启动时需要加载一些配置信息、用户末次操作信息&#xff0c;以及算法模型等数据时比较费时&#xff0c;笔者在程序启动时设计欢迎页或加载页等窗体来提示用户程序正在加载某些数据&#xff0c;加载…

【Java数据结构 -- 顺序表】

List和ArrayList与顺序表 一. List1.1 List介绍2.1 常见接口介绍3.1 List的使用 二. ArrayList与顺序表1.线性表2.顺序表2.1 接口的实现2.2 顺序表的创建2.3 顺序表的打印2.4 顺序表的插入2.5 顺序表的按索引位置插入数据2.6 判断顺序表是否包含某个数2.7 返回顺序表某个数的索…

谁会成为第一个MoE大模型基座呢?重磅!Mixtral MoE 8x7B!!!

文章目录 谁会成为第一个MoE大模型基座呢&#xff1f;重磅&#xff01;Mixtral MoE 8x7B&#xff01;&#xff01;&#xff01;前言重磅&#xff01;Mixtral MoE 8x7B&#xff01;&#xff01;&#xff01;Mixtral是啥模型介绍模型结构长啥样&#xff1f;表现如何&#xff1f;可…

Python从入门到精通五:Python数据容器

数据容器入门 为什么学习数据容器 思考一个问题&#xff1a;如果我想要在程序中&#xff0c;记录5名学生的信息&#xff0c;如姓名。 如何做呢&#xff1f; 学习数据容器&#xff0c;就是为了批量存储或批量使用多份数据 Python中的数据容器&#xff1a; 一种可以容纳多份…

HCIA-H12-811题目解析(10)

1、【单选题】DHCP客户端在租期到达哪个比例时第一次发送续租报文&#xff1f; 2、【单选题】在WLAN中用于标识无线网络&#xff0c; 区分不同的无线网络的是&#xff1f; 3、【单选题】我们在笔记本电脑上搜索可接入无线网络时&#xff0c;显示出来的网络名称实际是 4、【单…

哪些原因导致MES管理系统实施项目失败

在制造业中&#xff0c;实施MES管理系统是一种提高生产效率、降低成本、提升质量的重要手段。然而&#xff0c;许多MES管理系统实施项目并未取得预期的成功&#xff0c;甚至失败。本文将探讨导致MES管理系统实施项目失败的原因。 1、需求不明确 在MES实施项目中&#xff0c;需…

Java-异常(一)-异常的概述和常见异常的举例

&#x1f436;b站视频 124-异常处理-异常的概述与常见异常的举例_哔哩哔哩_bilibili 目录 b站视频 5.1 异常概念 5.2 Error 示例代码 5.3 Exception异常划分 ❓面试题&#xff1a;常见的异常有哪些&#xff1f;举例说明 &#x1f436;5.1 异常概念 在使用计算机语言进行…

基于SSM的校园心理健康网站的设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

PostGIS学习教程十二:地理

PostGIS学习教程十二&#xff1a;地理 坐标为"地理&#xff08;geographics&#xff09;“形式或者说是” 纬度&#xff08;latitude&#xff09;/经度&#xff08;longitude&#xff09;"形式的数据非常常见。 与Mercator&#xff08;墨卡托&#xff09;、UTM&…

【jitterbuffer】2:OnCompleteFrameCallback 送去FrameBuffer 处理的流程

【jitterbuffer】2:OnCompleteFrameCallback 送去FrameBuffer 处理的流程 基于m98版本。 WebRtc Video Receiver(六)-FrameBuffer原理 大神有个详细的论述。 Finder的FID设计 H.264 没有FID,使用RtpSeqNumOnlyRefFinder ,比较复杂,要做出决定 RtpSeqNumOnlyRefFinder cla…

canvas 有趣的弹簧效果

先上效果 两个小球之间有一根弹簧&#xff0c;这里有一条线表示&#xff0c;其中左球固定&#xff0c;在点击开始后&#xff0c;右球开始做自由落体 思路 先做受力分析 经过受力分析可以发现&#xff0c;整个系统一共有三个力在起作用&#xff0c;我们分别把他们求出来并合成…

鸿蒙原生应用再添新丁!同花顺入局鸿蒙

鸿蒙原生应用再添新丁&#xff01;同花顺入局鸿蒙 来自 HarmonyOS 微博12月11日消息&#xff0c;同花顺已完成#鸿蒙原生应用#beta版本&#xff0c;并正在进行全量版本开发&#xff0c;进一步丰富了#鸿蒙原生应用#的覆盖领域。同花顺作为股民和券商首选的一站式金融理财服务平台…

搜集怎么绘制三维曲线和曲面?

1、针对函数对象是单一变量、两个函数的情况。用plot3函数&#xff1b;&#xff08;三维曲线&#xff09; 看一下matlab官方的例子&#xff1a; t 0:pi/50:10*pi; st sin(t); ct cos(t); plot3(st,ct,t) 绘制出来的曲线&#xff1a; 几个比较关键的点&#xff1a; &…