Python 类和对象

news2024/12/27 3:49:09

一、什么是类和对象

Python和Java一样,都是面向对象的编程语言,面向对象编程其实是一种封装代码的方法,把一些公共的属性或者方法封装到一个类中,然后再通过这个类可以创建多个对象,最后使用这些对象去调用这些封装起来的公共的属性或者方法。

  • 类(Class):用来描述具有相同的属性和方法的对象的集合。类就好比现实生活中的印刷机的模板,这个模板是不能直接被使用的,模板的主要作用是用来创建对象的。
  • 对象:是通过类创建出的实例。就好比是印刷机通过模板印刷出来的一张张试卷,这些试卷才是真正被学生们使用的,而代码中也是通过对象进行调用的。
  • 方法:在类中定义的函数,和普通的函数所有不同的是,类方法必须有一个额外的第一个参数名称为self 的参数,这个self 参数代表的是当前对象。
  • 构造方法:是类中一个特殊的方法,方法名为__init__,主要用来创建类的对象实例的,该方法在创建实例的时候自动调用。可以不写构造方法,默认创建实例不做任操作,也可以在类中写__init__方法,__init__方法中可以带参数也可以不带参数,用来做一些初始化设置。
  • 类变量:定义在类中且所有方法外部,是所有实例对象的共享变量。类变量可以通过类名.类变量或者对象.类变量的方式进行引用,但是修改只能通过 类名.类变量的方式进行修改,不能通过对象.类变量来修改。
  • 实例变量:定义在类内部,方法内部,以self.变量名出现。实例变量属于实例对象私有,只能通过实例对象调用,不能通过类调用。
  • 继承:指的是一个派生类(子类)可以继承基类(父类)的属性和方法。通俗点讲,就是你父亲有一栋房,如果你是你父亲的继承人,那么就等于你也拥有这套房,可以随时进去住。
  • 方法重写:指的是子类可以改写继承的父类方法。通俗点讲,就是你觉得你父亲盖的这栋房子的装修不符合你的审美,你可以重新进行装修成你喜欢的样子。

二、类的定义以及对象的创建和使用

## 创建一个类
class Person:
    class_id = 123456  ## 类变量

    def __init__(self, sex):  ## 构造方法
        self.sex = sex 		## 实例变量

    def eat(self):		## 普通方法
    	self.food = "大米"	## 实例变量
        print("吃的食物是" + self.food)
    
    def run(self):		## 普通方法
    	self.class_id = "32145"	## 实例变量
 
## 通过类实例化对象
man = Person("男")

## 调用类变量,通过类名或者对象名都能调用
print(man.class_id)     ## 123456
print(Person.class_id)  ## 123456

## 修改类变量时,只能通过 类名.类变量 方式修改,所有实例对象都会随之改变
Person.class_id = 2222
print(man.class_id)		## 2222
print(Person.class_id)	## 2222

## 修改类变量时,如果通过 对象名.类变量 方式修改,是无法修改类变量的值的,其本质实际是给该对象新增了个实例变量
man.class_id = 2222
print(man.class_id)		## 2222
print(Person.class_id)	## 123456

## 调用实例变量
print(man.sex)  ## 男
print(Person.sex)  ## 报错,通过类名无法调用实例变量
print(man.food)	   ## 报错,因为man对象再此之前并没有调用eat()方法,所有此时并没有生成这个实例变量

## 调用方法
man.eat()  			## 吃的食物是大米
print(man.food)		## 大米

## 实例变量和类变量可以同名,但这种情况下使用类对象将无法调用类变量,它会首选实例变量,这也是不推荐“类变量使用对象名调用”的原因
man.run()
print(man.class_id)	  ## 32145

## 使用对象名来修改实例变量的值的时候,不会影响类的其它实例化对象,更不会影响同名的类变量
woman = Person("女")
woman.sex = "woman"
print(woman.sex)    ## woman
print(man.sex)		## 男

三、实例方法、类方法和静态方法

  1. 实例方法:通常情况下,在类中定义的方法默认都是实例方法,构造方法也属于一种特殊的实例方法。实例方法最大的特点就是,它最少也要包含一个 self 参数,用于绑定调用此方法的实例对象(Python 会自动完成绑定)。实例方法通常会用类对象直接调用,也支持使用类名调用实例方法,但此方式需要手动给 self 参数传值。
class Person:
    def __init__(self, sex):
        self.sex = sex

    def eat(self):
        self.food = "大米"

## 类对象直接调用
man = Person("男")
man.eat()

## 类名调用实例方法,但此方式需要手动给 self 参数传值
Person.eat(man)
  1. 类方法:类方法和实例方法相似,它最少也要包含一个参数,只不过类方法中通常将其命名为 cls,会自动将类本身绑定给 cls 参数,还有就是类方法需要使用@classmethod修饰符进行修饰。类方法推荐使用类名直接调用,当然也可以使用实例对象来调用(不推荐)。
class Person:
    @classmethod
    def info(cls):
        print(name + ":" + sex)

# 使用类名直接调用类方法
Person.info()

#使用类对象调用类方法
p = Person()
p.info()
  1. 静态方法:其实就是在普通函数使用@staticmethod注解来修饰。静态方法没有类似 self、cls 这样的特殊参数,因此 Python 解释器不会对它包含的参数做任何类或对象的绑定。也正因为如此,类的静态方法中无法调用任何类属性和类方法。静态方法的调用,既可以使用类名,也可以使用类对象。
class Person:
    @staticmethod
    def info(name, sex):
        print(name + ":" + sex)
 
## 使用类名调用
Person.info("Tom", "男")

## 使用类对象调用
p = Person("女")
p.info("xiaohong", "nv")

四、封装

封装指的是在设计类时,刻意地将一些属性和方法隐藏在类的内部,这样就无法在外部通过类对象直接访问,只能在本类中使用。封装的主要目的是w为了保证类内部数据结构的完整性,避免外部对内部数据的影响,提高了程序的可维护性。除此之外,对类进行良好的封装,还可以提高代码的复用性。

  1. 类如何进行封装
    Python 类中的变量和函数在进行封装的时候不像Java封装的使用的(public、private)等修饰符,Python 没有使用修饰符,而是在变量名或者函数名左边添加__双下划线来区分,没有__则表示是公有的(类似 public 属性),有__则表示是私有的(类似 private)。Java中封装使用的修饰符有四种,而Python 中只只有两种,要么是公有的,要么是私有的。公有属性的类变量和类函数,在类的外部、类内部以及子类中,都可以正常访问;私有属性的类变量和类函数,只能在本类内部使用,类的外部以及子类都无法使用。
class Test:
    __id = 1
    name = "haha"

    def __get_id(self):
        print(self.__id)

    def set_id(self, id):
        self.__id = id
        print(self.__id)

在这里插入图片描述

五、继承

继承指的是子类(派生类)会继承父类(基类)属性和方法。Python 支持多继承,使用多继承经常需要面临的问题是,多个父类中包含同名的类方法该继承哪个父类的方法,Python 的处置措施是:根据子类继承多个父类时这些父类的前后次序决定,即排在前面父类中的类方法会覆盖排在后面父类中的同名类方法。

class Test1:
    __id = 1
    name = "Tom"
    
    def __init__(self):
        self.sex = "nan"
        print("执行Test1")

    def __get_id(self):
        print("get Test1 中的id: " + str(self.__id))

    def set_id(self, id):
        self.__id = id
        print("set Test1 中的id: " + str(self.__id))

class Test2:
    __id = 2
    name = "Jack"

    def __get_id(self):
        print("get Test2 中的id: " + str(self.__id))

    def set_id(self, id):
        self.__id = id
        print("set Test2 中的id: " + str(self.__id))
 
## 创建一个子同时类继承Test1和Test2
class TestSub(Test1, Test2):
    def __init__(self):
        pass

## 创建一个子类对象
s = TestSub()

1.通过子类对象可以直接调用父类的公有属性和方法,在多继承且父类中存在同名属性或者同名方法时使用最左边的父类中的属性或者方法
print(s.name)   ## Tom
s.set_id(3)		## set Test1 中的id: 3

2.子类中包含__init__方法时,如果不手动写名,子类不会去调用父类中的__init__()方法
print(s.sex)   ## 会报错,AttributeError: 'TestSub' object has no attribute 'sex'

3.如需继续调用父类的 __init__() 方法,必须在子类的 __init__() 中添加对父类 __init__() 方法的调用,有两种方式
## 方式一:通过父类名直接调用
class TestSub(Test1, Test2):
    def __init__(self):
        Test1.__init__(self)
        pass
## 方式二:通过super()方法调用
class TestSub(Test1, Test2):
    def __init__(self):
        super().__init__()
        pass
 
4.父类与子类__init__方法的执行顺序,是按照子类的__init__方法从上往下顺序执行代码
class TestSub(Test1, Test2):
    def __init__(self):
        super().__init__()
        print("执行TestSub")
        pass
## 执行结果为:
执行Test1
执行TestSub

class TestSub(Test1, Test2):
    def __init__(self):
        print("执行TestSub")
        super().__init__()
        pass
## 执行结果为:
执行TestSub
执行Test1

5.重写父类的__init__方法
class TestSub(Test1, Test2):
    def __init__(self):
        print("执行TestSub")
        super().__init__()
        self.sex = "nv"
        pass

## 通过子类对象调用重写过的父类属性
s = TestSub()
print(s.sex)   ## nv

6.强制调用父类私有属性或者私有方法,子类不能够直接调用父类中的私有方法,
其实是编译器把这个方法的名字改成了"_父类名__私有方法名()"的形式,如果强制调用,可以如下所示:
class TestSub(Test1):
    def get_id(self):
        print(super()._Test1__id)
        super()._Test1__get_id()

s = TestSub()
s.get_id()
## 调用结果如下:
1
get Test1 中的id: 1

六、多态

多态其实指的是父类可以存在多种类型的子类,调用的时候则是根据实际的类型去调用该类型的属性或者方法。就好比生活中可以把动物当作是一个父类,那么动物可以有很多种,比如:猫、狗它们都属于不同的种类的动物,这些不同的种类就可以称为多态。多态最主要的两个特征就是:
(1)继承:多态一定是发生在子类和父类之间;
(2)重写:子类重写了父类的方法。

1.首先定义一个动物类当作父类,并且定义动物都具有吃东西的方法
class Animal:
    def eat(self):
        print("动物都会吃东西")

2.再定义一个狗类继承动物类,并重写动物类的吃东西的方法,改成狗吃的是狗粮
class Dog(Animal):
    def eat(self):
        print("狗吃的是狗粮")

2.再定义一个猫类继承动物类,并重写动物类的吃东西的方法,改成猫吃的是猫粮      
class Cat(Animal):
    def eat(self):
        print("猫吃的是猫粮")

## 当我们(相当于变量a)问动物会不会吃东西的时候,这时就会调用Animal类的eat()方法
a = Animal()
a.eat()  ## 动物都会吃东西

## 当我们(相当于变量a)狗吃什么的时候,这时就会调用Dog类的eat()方法
a = Dog()
a.eat()	 ## 狗吃的是狗粮

## 当我们(相当于变量a)猫吃什么的时候,这时就会调用Cat类的eat()方法
a = Cat()
a.eat()	 ## 猫吃的是猫粮

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

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

相关文章

【教程】两种免费更新iOS17测试版的方法

苹果iOS17系统已经发布,目前所有用户都可以免费注册成为开发者,升级iOS17开发者测试版 注意,现在不是通过描述文件来更新系统了,给大家带来两种更新升级方法,看下文操作 方法一 苹果官网注册 按照下图发消息“更新” …

java设计模式(十六)命令模式

目录 定义模式结构角色职责代码实现适用场景优缺点 定义 命令模式(Command Pattern) 又叫动作模式或事务模式。指的是将一个请求封装成一个对象,使发出请求的责任和执行请求的责任分割开,然后可以使用不同的请求把客户端参数化&a…

数据库篇——锁

目录 引文A——活锁 引文B——死锁 1、表锁 1.1 关于 S 锁 1.2 关于 X 锁 1.3 关于意向锁 2、行锁 2.1 关于记录锁 2.2 关于间隙锁 2.3 关于临键锁 2.4 关于插入意向锁 3、页锁 我们在谈表锁、行锁以及页锁之前,先聊一聊 活锁🔒与 死锁🔒的…

RabbitMQ安装、端口修改、简单的角色介绍

前提 本文介绍RabbitMQ安装的环境是CentOS7版本的Linux云服务器。 官网:https://www.rabbitmq.com/ RabbitMQ的安装 由于RabbitMQ是使用Erlang语言开发的,所以我们在安装RabbitMQ之前需要在服务器中安装Erlang语言的环境。在Linux中执行下面命令&…

Day_43插入排序

目录 一. 关于插入排序 1. 排序的定义 2. 插入排序 二. 插入排序的实现过程 三. 代码实现过程 1. 插入排序核心代码 四. 代码展示 五. 数据测试 六. 总结 一. 关于插入排序 1. 排序的定义 排序,就是重新排列表中的元素,使表中的元素满足按关键字有序…

AIGC与AidLux互联应用——AidLux端AIGC测评(二)PC端云端Stable Diffusion模型推理应用(文生图,图生图)

在这里插入图片描述 Stable Diffusion模型搭建首先下载diffusers,然后安装,命令如下: git clone https://github.com/huggingface/diffusers.git pip install diffusers cd diffusers pip install . ubuntu和win系统下都可以 文生图&#x…

React Hooks 组件化开发(常用)

本文章视频地址:视频链接 一、React组件分类 二、Hook函数概览 Hook 是 React 16.8 的新增特性!并且只能运用到函数组件中! 1.useState 作用:在函数组件中使用状态,修改状态值可让函数组件更新,类似于类…

鸿蒙初识

学习官网:https://www.harmonyos.com/cn/develop 准备 注册,安装软件(node:12, DevEco Studio): 在实际开发中node最好使用nvm进行版本管理。 https://developer.harmonyos.com/cn/docs/documentation/doc-guides/software_install-00000010…

ChatGPT-Plugins-Searchable

ChatGPT Plus 用户应该都知道Plus已经开放了插件功能,但是在插件商店里存在一个较大的问题插件数量超过100款,却没有便捷的搜索功能。 而我们在查找一款插件时,需要从插件商店的第一页点击到最后一页一个个找,显然这非常的麻烦。 …

驱动开发--驱动模块

目录 1.驱动模块 hello.c Makefile 2.内核中的打印函数(编写第一个驱动程序) Source Insight 使用: 3.打印函数编写 分析 4、驱动的多文件编译 5、模块传递参数 6、安装好驱动之后如何传参? 7、字符设备驱动 8、字符设…

chatgpt赋能python:Python如何突破VIP限制

Python如何突破VIP限制 在这个数字内容时代,我们经常使用各种网站和应用程序来获取视频、音乐、软件等数字资源。但是,某些资源可能受到VIP限制,这意味着我们需要付费才能获得完整的访问权限。但是,如果你了解Python编程&#xf…

Agile | 聊聊敏捷开发

什么是敏捷开发 敏捷开发是一种迭代和增量的项目管理方法,优先考虑适应性、协作和快速交付,而不是遵循严格的计划[0]。它是在《敏捷软件开发宣言》和《12项原则》中表达的一组价值观和原则[1]。敏捷是基于这些价值观和原则的一组框架和实践的总称。敏捷…

【数据库】修改数据库密码及端口

一、修改MySQL配置文件 想要在没有密码的状态下修改MySQL的密码,必须跳过MySQL登录时的登录密码权限的验证,取消掉这个验证的方式如下: 1、找到MySQL的安装文件中的my.ini文件 一般人应该能找到的吧,配置MySQL的环境变量中也有安…

关于数据中心机房动环监控系统的应用与设计 安科瑞 许敏

摘 要: 机房动力和环境监控系统是对分布的精密机房及通信局(站)内的电源、空调、油机、蓄电池、高低压配电等多种设备和环境的各种参数、图像、声音等进行遥测、并对设备进行集中监控、集中维护和集中管理,是现代化机房管理手段和…

【Leetcode -138.复制带随机指针的链表 -2130.链表最大孪生和】

Leetcode Leetcode -138.复制带随机指针的链表Leetcode -2130.链表最大孪生和 Leetcode -138.复制带随机指针的链表 题目:给你一个长度为 n 的链表,每个节点包含一个额外增加的随机指针 random ,该指针可以指向链表中的任何节点或空节点。 构…

chatgpt赋能python:Python如何设置画笔颜色

Python如何设置画笔颜色 在Python中,有很多库可以用来画图,比如常用的Matplotlib、Seaborn和Plotly等等,但无论是哪种库,设置画笔颜色都是非常基础且重要的操作,因为它可以让我们更好地展示数据图表,突出重…

【TCP/IP】基于UDP的服务器端/客户端实现 II - 实践与实现

基于UDP的回声服务器端/客户端 结合之前基于TCP实现的回声服务器&#xff0c;我们尝试再用UDP来完成对回声服务器/客户端的设计。 echo_server: #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <arpa…

内蒙古自治区关于加快充换电基础设施建规划 安科瑞 许敏

摘要&#xff1a;为深入贯彻落实《国务院办公厅关于印发新能源汽车产业发展规划&#xff08;2021—2035年&#xff09;的通知》&#xff08;国办发 ﹝2020﹞39号&#xff09;、《国家发展改革委等部门关于进一步提升电动汽车充电基础设施服务保障能力的实施意见》&#xff08;发…

异常值检验(t分布查表)、方差分析

异常值检验 T-test 参考&#xff1a;1.ttest和ttest2 区别 2. ttest在 matlab 3.T test分布表 单侧 方差分析&#xff08;ANOVA&#xff09; Def: 方差分析&#xff08;analysis of variance, ANOVA&#xff09;是一种统计检验&#xff0c;用于检验两组或更多组样本的均值是…

PRL:上海交大张文涛团队实现量子材料相关突破

来源&#xff1a;上海交通大学 近期&#xff0c;上海交通大学物理与天文学院张文涛研究组利用自行研制的高能量和高时间分辨率角分辨光电子能谱系统对量子材料1T-TiSe₂电子结构进行了超快激光操控研究。利用超快光激发与电荷密度波相有关的相干声子&#xff0c;引起晶格内原子…