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

news2024/9/21 12:42:12

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()  # 通过类名访问(推荐)

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

案例课6——追一科技

1.公司介绍 追一科技是一家企业级智能服务AI公司&#xff0c;创立于2016年3月&#xff0c;主攻深度学习和自然语言处理&#xff0c;为金融、零售、生活服务等领域企业提供智能服务系统和解决方案。 追一科技的智能服务系统AIforce&#xff0c;拥有AI语义理解能力、智能产品矩阵…

【Android】完美解决Cannot resolve method ‘subscribe(Observer<T>)‘

问题截图&#xff1a; 解决方法&#xff1a; 如上图&#xff0c;看我标123的三个地方&#xff0c;2标注的地方提示我们我方法实际返回的值是Observer<Res_GetCellCode>,而我想要返回的结果是&#xff1a;3标记的结果&#xff1a;Observer<Res_QueryCTInfo>&#xf…

python自动化运维快速入门,python自动化运维教程

大家好&#xff0c;给大家分享一下python自动化运维需要掌握的技能&#xff0c;很多人还不知道这一点。下面详细解释一下。现在让我们来看看&#xff01; 面向学员 熟练使用计算机&#xff0c;对Windows、Linux 有一点了解从业职或在校学生 对目前从事互联网运维&#xff0c;想…

js 生成分享码或分享口令

代码 function getShareToken(length) {var characters ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789;var shareToken ;for (var i 0; i < length; i) {var randomIndex Math.floor(Math.random() * characters.length);var randomChar character…

亚马逊云科技Amazon Bedrock,现推出更多模型选择和全新强大功能

亚马逊云科技在re:Invent 2023上宣布推出Amazon Bedrock更多模型选择和强大功能&#xff0c;帮助客户更轻松地构建和规模化针对其业务定制的生成式AI应用程序。 Amazon Bedrock是一项全面托管的服务&#xff0c;用户可轻松访问来自AI21 Labs、Anthropic、Cohere、Meta、Stabili…

CRM的作用:强化客户忠诚度和提升业务效益

随着国内市场的不断发展和企业数字化进程持续进行&#xff0c;许多人在工作和生活中或多或少都对CRM客户关系管理系统有所耳闻&#xff0c;但可能并不清楚CRM管理系统具体是什么&#xff0c;以及都有什么作用。这篇文章带您全面了解一下&#xff0c;CRM是什么&#xff0c;以及C…

java-两个列表进行比较,判断那些是需要新增的、删除的、和更新的

文章目录 前言两个列表进行比较&#xff0c;判断那些是需要新增的、删除的、和更新的 前言 如果您觉得有用的话&#xff0c;记得给博主点个赞&#xff0c;评论&#xff0c;收藏一键三连啊&#xff0c;写作不易啊^ _ ^。   而且听说点赞的人每天的运气都不会太差&#xff0c;实…

02基于matlab的卡尔曼滤波

基于matlab的卡尔曼滤波&#xff0c;可更改状态转移方程&#xff0c;控制输入&#xff0c;观测方程&#xff0c;设置生成的信号的噪声标准差&#xff0c;设置状态转移方差Q和观测方差R等参数&#xff0c;程序已调通&#xff0c;需要直接拍下。

bootstrap:下拉菜单

<!DOCTYPE html> <html> <head> <meta charset"UTF-8"> <title>下拉菜单DEMO</title> <link rel"stylesheet" type"text/css" href"/cdn.bootcss.com/bootstrap/3.3.2/css/bootstrap.min.css"…

加减乘除简单吗?不,一点都不,利用位运算实现加减乘除(代码中不含+ - * /)

文章目录 &#x1f680;前言&#x1f680;异或运算以及与运算&#x1f680;加法的实现&#x1f680;减法的实现&#x1f680;乘法的实现&#x1f680;除法的实现 &#x1f680;前言 这也是阿辉开的新专栏&#xff0c;知识将会很零散不成体系&#xff0c;不过绝对干货满满&…

螺旋方阵-2d

Description 一个 n 行 n 列的螺旋方阵按如下方法生成&#xff1a;从方阵的左上角&#xff08;第 1 行第 1 列&#xff09;出发&#xff0c;初始时向右移动&#xff1b;如果前方是未曾经过的格子&#xff0c;则继续前进&#xff1b;否则&#xff0c;右转。重复上述操作直至经过…

【离散数学】——期末刷题题库( 二元关系)

&#x1f383;个人专栏&#xff1a; &#x1f42c; 算法设计与分析&#xff1a;算法设计与分析_IT闫的博客-CSDN博客 &#x1f433;Java基础&#xff1a;Java基础_IT闫的博客-CSDN博客 &#x1f40b;c语言&#xff1a;c语言_IT闫的博客-CSDN博客 &#x1f41f;MySQL&#xff1a…

CAVLC(基于上下文自适应的可变长编码)

以1个4 x 4的图像块为例,来说明CAVLC的编码及解码过程。 编码 ZIG-ZAG排列 ZIG-ZAG排列后的序列为: 计算非零系数数目和拖尾系数数目 TotalCoeffs:非零系数数目。变换系数level中所有不为0的level的数目,本例中为5。 TrailingOnes:拖尾系数的数目。指的是矩阵重排列后…

系统韧性研究(7)| 韧性系统的16大指导原则

不良事件和条件可能会中断系统&#xff0c;导致系统无法提供必要的功能和服务。正如我在本系列的前几篇文章中所概述的那样&#xff0c;韧性是大多数系统的一个基本质量属性&#xff0c;因为它们提供了关键的能力和服务&#xff0c;尽管存在着不可避免的困难&#xff0c;但这些…

部署Nextcloud详细步骤及优化方法

一、安装PHP8.0以上 我这里使用PHP8.0.30 [rootlocalhost ~]# php -v PHP 8.0.30 (cli) (built: Aug 3 2023 17:13:08) ( NTS gcc x86_64 ) Copyright (c) The PHP Group Zend Engine v4.0.30, Copyright (c) Zend Technologies [rootlocalhost ~]# 安装方法参考 二、安装MY…

台式扫描电镜中的扫描速度和扫描模式如何选择?

台式扫描电镜&#xff08;SEM&#xff09;是一种利用电子束扫描样品表面&#xff0c;通过检测样品反射或发射的次级电子、背散射电子、X 射线等信号&#xff0c;来获取样品的形貌、结构、组成和分布等信息的仪器。台式扫描电镜具有体积小、操作简单、样品制备方便、分辨率高、成…

2023年团体程序设计天梯赛——总决赛题

F-L1-1 最好的文档 有一位软件工程师说过一句很有道理的话&#xff1a;“Good code is its own best documentation.”&#xff08;好代码本身就是最好的文档&#xff09;。本题就请你直接在屏幕上输出这句话。 输入格式&#xff1a; 本题没有输入。 输出格式&#xff1a; 在一…

禾匠榜店商城系统 RCE漏洞复现

0x01 产品简介 禾匠榜店商城系统是浙江禾匠信息科技有限公司的一套基于PHP和MySQL的商城系统。 0x02 漏洞概述 禾匠榜店商城系统的api/testOrderSubmit模块下的preview方法存在命令执行漏洞,攻击者可以向服务器写入木马文件,直接获取服务器权限 0x03 漏洞概述 FOFA:bod…

GZ029 智能电子产品设计与开发赛题第6套

2023年全国职业院校技能大赛高职组 “GZ029智能电子产品设计与开发”赛项赛卷六 题目&#xff1a;模拟工业传送带物品检测系统的设计与开发 1 竞赛任务 在智能电视机上播放工业传送带传输物品视频&#xff0c;模拟工业传送带物品检测系统&#xff08;以下简称物品检测系统&…

Vue路由跳转重定向动态路由VueCli

Vue路由跳转&重定向&动态路由&VueCli 一、声明式导航-导航链接 1.需求 实现导航高亮效果 如果使用a标签进行跳转的话&#xff0c;需要给当前跳转的导航加样式&#xff0c;同时要移除上一个a标签的样式&#xff0c;太麻烦&#xff01;&#xff01;&#xff01; …