Python 基础:类

目录

  • 一、类的概念
  • 二、定义类
  • 三、创建对象并进行访问
  • 四、修改属性的值
    • 方法一:句点表示法直接访问并修改
    • 方法二:通过方法进行修改
  • 五、继承
    • 继承父类属性和方法
    • 重写父类方法
  • 六、将实例用作属性
  • 七、导入类
    • 导入单个类
    • 从一个模块中导入多个类
    • 导入整个模块
    • 导入模块中的所有类
  • 八、一些代码编写规范

遇到看不明白的地方,欢迎在评论中留言呐,一起讨论,一起进步!
在这里插入图片描述
本文参考:《Python编程:从入门到实践(第2版)》

一、类的概念

是是一种定义对象结构的方式,它包含了属性(变量)和行为(方法),这些行为的代码可以操作这些变量。类可以看作是一个模板,用来创建具有相同属性和方法的对象实例。通过类,我们可以实例化出各种各样具体的对象

在这里插入图片描述

二、定义类

定义一个类非常简单,只需要使用 class 关键字,后面跟着类名(首字母大写),然后是冒号。类体中的代码块定义了类的属性和方法。

class Car:
    def __init__(self, make, model, year):
        self.make = make
        self.model = model
        self.year = year

    def description(self):
        return f"{self.year} {self.make} {self.model}"

在上面的例子中,Car 是一个类,它有三个属性:makemodelyear

__init__(开头结尾都有两个下划线)方法是一个特殊的方法,被称为类的构造器,它在创建类的新实例时自动调用。在这个方法中,形参 self 必不可少。

__init__ 方法中,我们可以指定属性的默认值,下面来添加一个名为 odometer_reading 的属性,其初始值总是为 0:

class Car:
    def __init__(self, make, model, year):
        self.make = make
        self.model = model
        self.year = year
        self.odometer_reading = 0  # 指定属性的默认值
    ...

注:方法的第一个参数总是 self,它代表当前对象的实例。

三、创建对象并进行访问

一旦定义了一个类,就可以使用它来创建对象。在Python中,我们使用 ClassName() 的方式来创建一个类的新实例,这时会自动调用方法 __init__,并使用提供的值来设置对象的属性。这种方式最后会返回一个对象的实例,我们再将这个实例赋值给一个变量(小写字母表示)进行存储。

my_car = Car("Toyota", "Corolla", 2020)

要访问实例的属性,使用句点表示法:对象变量.属性名

print(my_car.year)

要调用实例的方法,也使用句点表示法:对象变量.方法名()

print(my_car.description())

我们可以根据一个类创建任意数量的实例,这些实例都存储在不同的变量中,互不影响。

四、修改属性的值

方法一:句点表示法直接访问并修改

class Car:
    def __init__(self, make, model, year):
        self.make = make
        self.model = model
        self.year = year
        self.odometer_reading = 0  # 指定属性的默认值
    ... 

my_car = Car("Toyota", "Corolla", 2020)
print(my_car.description())
my_car.odometer_reading = 23  # 直接修改属性的值
print(my_car.description())

执行结果:
在这里插入图片描述

方法二:通过方法进行修改

class Car:
    def __init__(self, make, model, year):
        self.make = make
        self.model = model
        self.year = year
        self.odometer_reading = 0

    def update_odometer(self, mileage):
        """将里程表读数设置为指定的值。"""
        self.odometer_reading = mileage

    def description(self):
        return f"{self.year} {self.make} {self.model} {self.odometer_reading}"


my_car = Car("Toyota", "Corolla", 2020)
print(my_car.description())
my_car.update_odometer(99)  # 通过方法修改
print(my_car.description())

执行结果:
在这里插入图片描述

五、继承

继承父类属性和方法

编写类时,并非总是要从空白开始。如果要编写的类是另一个现成类的特殊版本,可使用继承。一个类继承另一个类时,将自动获得另一个类的所有属性和方法。原有的类称为父类,而新类称为子类。子类继承了父类的所有属性和方法,同时还可以定义自己的属性和方法。

在既有类的基础上编写新类时,通常要调用父类的方法super().init()。这将初始化在父类__init__()方法中定义的所有属性,从而让子类包含这些属性。

super() 是一个特殊函数,让子类能够调用父类的方法。父类也称为超类 (superclass),名称 super 由此而来。

在下面的例子中,ElectricCar 类继承了 Car 类,并添加了一个新的属性 battery_size 和相应的方法。

class Car:
    def __init__(self, make, model, year):
        self.make = make
        self.model = model
        self.year = year
        self.odometer_reading = 0
    ...

class ElectricCar(Car):  # 注意格式
    def __init__(self, make, model, year, battery_size):
        super().__init__(make, model, year)  # 要调用父类的__init__()方法
        self.battery_size = battery_size

    def display_battery(self):
        return f"Battery size: {self.battery_size} kWh"

👉 这里有几点需要注意:

  1. 创建子类时,父类必须包含在当前文件中,且位于子类前面
  2. 定义子类时,必须在圆括号内指定父类的名称

重写父类方法

重写父类的方法时,可在子类中定义一个与要重写的父类方法同名的方法。这样,Python 将不会考虑这个父类方法,而只关注你在子类中定义的相应方法。

假设 Car 类有一个名为 fill_gas_tank() 的方法,它对全电动汽车来说毫无意义,因此你可能想重写它。下面演示了一种重写方式:

class ElectricCar(Car):
    -...

    def fill_gas_tank(self):
        """电动汽车没有油箱。"""
        print("This car doesn't need a gas tank!")
    ...

现在,如果有人对电动汽车调用方法 fill_gas_tank(),Python 将忽略 Car 类中的方法 fill_gas_tank(),转而运行上述代码。

使用继承时,可让子类保留从父类那里继承而来的精华,并剔除不需要的糟粕。

六、将实例用作属性

有时可能需要将类的一部分提取出来,作为一个独立的类,这样可以将大型类拆分成多个协同工作的小类。

class Car:
    def __init__(self, make, model, year):
        self.make = make
        self.model = model
        self.year = year
        self.odometer_reading = 0

    def update_odometer(self, mileage):
        """将里程表读数设置为指定的值。"""
        self.odometer_reading = mileage

    def description(self):
        return f"{self.year} {self.make} {self.model} {self.odometer_reading}"

class Battery:
    """一次模拟电动汽车电瓶的简单尝试。"""
    def __init__(self,battery_size=75):
        """初始化电瓶的属性。"""
        self.battery_size = battery_size

    def describe_battery(self):
        """打印一条描述电瓶容量的消息。"""
        print(f"This car has a {self.battery_size}-kWh battery.")

class ElectricCar(Car):
    """电动汽车的独特之处。"""
    def __init__(self,make,model,year):
        """
        初始化父类的属性。
        再初始化电动汽车特有的属性。
        """
        super().__init__(make,model,year)
        self.battery = Battery()  # 将实例用作属性

my_tesla = ElectricCar('tesla','model s',2019)
my_tesla.battery.describe_battery()

执行结果:
在这里插入图片描述

七、导入类

Python 允许将类存储在模块中,然后在主程序中导入所需的模块。

导入单个类

car.py:(模块,文件名 car 就是模块名)

"""一个可用于表示汽车的类。"""
class Car:
    """一次模拟汽车的简单尝试。"""

    def __init__(self,make,model,year):
        """初始化描述汽车的属性。"""
        self.make = make
        self.model = model
        self.year = year
        self.odometer_reading = 0

    def get_descriptive_name(self):
        """返回整洁的描述性名称。"""
        long_name = f"{self.year} {self.make} {self.model}"
        return long_name.title()

    def read_odometer(self):
        """打印一条消息,指出汽车的里程。"""
        print(f"This car has {self.odometer_reading} miles on it.")

    def update_odometer(self,mileage):
        """
        将里程表读数设置为指定的值。
        拒绝将里程表往回调。
        """
        if mileage >= self.odometer_reading:
            self.odometer_reading = mileage
        else:
            print("You can't roll back an odometer!")

    def increment_odometer(self,miles):
        """将里程表读数增加指定的量。"""
        self.odometer_reading += miles

my_car.py:(主程序)

from car import Car

my_new_car = Car('audi','a4',2019)
print(my_new_car.get_descriptive_name())

my_new_car.odometer_reading = 23
my_new_car.read_odometer()

执行结果:
在这里插入图片描述

从一个模块中导入多个类

car.py:(模块)

"""一组用于表示燃油汽车和电动汽车的类。"""
class Car:
    """一次模拟汽车的简单尝试。"""

    def __init__(self,make,model,year):
        """初始化描述汽车的属性。"""
        self.make = make
        self.model = model
        self.year = year
        self.odometer_reading = 0

    def get_descriptive_name(self):
        """返回整洁的描述性名称。"""
        long_name = f"{self.year} {self.make} {self.model}"
        return long_name.title()

    def read_odometer(self):
        """打印一条消息,指出汽车的里程。"""
        print(f"This car has {self.odometer_reading} miles on it.")

    def update_odometer(self,mileage):
        """
        将里程表读数设置为指定的值。
        拒绝将里程表往回调。
        """
        if mileage >= self.odometer_reading:
            self.odometer_reading = mileage
        else:
            print("You can't roll back an odometer!")

    def increment_odometer(self,miles):
        """将里程表读数增加指定的量。"""
        self.odometer_reading += miles

class Battery:
    """一次模拟电动汽车电瓶的简单尝试。"""

    def __init__(self,battery_size=75):
        """初始化电瓶的属性。"""
        self.battery_size = battery_size

    def describe_battery(self):
        """打印一条描述电瓶容量的消息。"""
        print(f"This car has a {self.battery_size}-kWh battery.")

    def get_range(self):
        """打印一条描述电瓶续航里程的消息。"""
        if self.battery_size == 75:
            range = 260
        elif self.battery_size == 100:
            range = 315

        print(f"This car can go about {range} miles on a full charge.")

class ElectricCar(Car):
    """模拟电动汽车的独特之处。"""

    def __init__(self,make,model,year):
        """
        初始化父类的属性。
        再初始化电动汽车特有的属性。
        """
        super().__init__(make,model,year)
        self.battery = Battery()

my_cars.py:(主程序)

from car import Car,ElectricCar  # 多个类用逗号分隔

my_beetle = Car('volkswagen','beetle',2019)
print(my_beetle.get_descriptive_name())

my_tesla = ElectricCar('tesla','roadster',2019)
print(my_tesla.get_descriptive_name())

执行结果:
在这里插入图片描述

导入整个模块

还可以导入整个模块,再使用句点表示法访问需要的类
my_cars.py:(主程序)

import car

my_beetle = car.Car('volkswagen','beetle',2019)  # 句点表示法
print(my_beetle.get_descriptive_name())

my_tesla = car.ElectricCar('tesla','roadster',2019)  # 句点表示法
print(my_tesla.get_descriptive_name())

导入模块中的所有类

from module_name import *

不推荐使用这种导入方式。这种方式可能引发名称方面的同名问题,难以诊断。

需要从一个模块中导入很多类时,最好导入整个模块,并使用 模块名.类名 语法来访问类

八、一些代码编写规范

类名应采用驼峰命名法,即将类名中的每个单词的首字母都大写,而不使用下划线。
实例名模块名都采用小写格式,并在单词之间加上下划线

对于每个类,都应紧跟在类定义后面包含一个文档字符串,简要地描述类的功能。
每个模块也都应包含一个文档字符串,对其中的类可用于做什么进行描述。

在类中,可使用一个空行来分隔方法。
而在模块中,可使用两个空行来分隔类。

先编写导入标准库模块的 import 语句,再添加一个空行,然后编写导入自己编写的模块的 import 语句

在这里插入图片描述

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

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

相关文章

效果超越ControlNet+IP-Adapter和FreeControl!Ctrl-X:可控文生图新框架(加州大学英伟达)

文章链接:https://arxiv.org/pdf/2406.07540 项目链接:https://genforce.github.io/ctrl-x/ 最近的可控生成方法,如FreeControl和Diffusion Self-guidance,为文本到图像(T2I)扩散模型带来了细粒度的空间…

机器学习(V)--无监督学习(一)聚类

根据训练样本中是否包含标签信息,机器学习可以分为监督学习和无监督学习。聚类算法是典型的无监督学习,目的是想将那些相似的样本尽可能聚在一起,不相似的样本尽可能分开。 相似度或距离 聚类的核心概念是相似度(similarity)或距离(distance…

模板方法模式和命令模式

文章目录 模板方法模式1.引出模板模式1.豆浆制作问题2.基本介绍3.原理类图 2.豆浆制作代码实现1.类图2.SoyaMilk.java 豆浆的抽象类3.PeanutSoyaMilk.java 花生豆浆4.RedBeanSoyaMilk.java 红豆豆浆5.Client.java6.结果 3.钩子方法1.基本介绍2.代码实现1.SoyaMilk.java 添加钩子…

数据中台-知识图谱平台

【数据分析小兵】专注数据中台产品领域,覆盖开发套件,包含数据集成、数据建模、数据开发、数据服务、数据可视化、数据治理相关产品以及相关行业的技术方案的分享。对数据中台产品想要体验、做二次开发、关注方案资料、做技术交流的朋友们,可以关注我。 1. 概述 随着…

弗洛伊德算法——C语言

弗洛伊德算法,是一种用于解决所有顶点对之间最短路径问题的经典算法,该算法通过动态规划的方法计算出从每个顶点到其他所有顶点的最短路径。 弗洛伊德算法的基本思想是逐步考虑每一个顶点作为中间点,更新所有顶点对之间的最短路径。它通过以…

开源模型应用落地-LangChain高阶-LCEL-表达式语言(七)

一、前言 尽管现在的大语言模型已经非常强大,可以解决许多问题,但在处理复杂情况时,仍然需要进行多个步骤或整合不同的流程才能达到最终的目标。然而,现在可以利用langchain来使得模型的应用变得更加直接和简单。 LCEL是什么&…

STM32CubeMX配置-RTC周期唤醒

一、简介 MCU为STM32G070,采用内部时钟32KHZ,配置为周期6s唤醒,调用回调函数,进行喂狗操作。 二、配置 初始时间、日期、周期唤醒时间配置。 开启周期唤醒中断 三、生成代码 调用回调函数,进行喂狗操作。 //RTC唤醒回…

vue-i18n使用步骤详解(含完整操作步骤)

开篇 下面是从创建vue项目开始,完整使用i18n实现国际化功能的步骤,希望对您有所帮助。 完整步骤 创建项目 创建项目,并在创建项目的时候选择vuex,router 选择3.x版本 后面随意选即可,下面是完整的代码结构 安装vue-i18n,并封装…

数据库事务隔离级别

前几天项目上合作公司的系统出现了一次死锁,突然想到由于近几年开发设计的系统并发用户比较少,很久没有碰到过死锁了,因此对死锁的概念也比较生疏了,需要温习一下。 事务 先从最基本的概念开始,事务、及其ACID特性。…

牛客热题:最长上升子序列(一)

📟作者主页:慢热的陕西人 🌴专栏链接:力扣刷题日记 📣欢迎各位大佬👍点赞🔥关注🚓收藏,🍉留言 文章目录 牛客热题:最长上升子序列(一)题目链接方法…

浅谈赚钱的四个级别,你在哪一层呢

一谈到赚钱,很多人都会扯到:智商、情商、人脉、资源、背景等等,类似“小钱靠勤,中钱靠智,大钱靠德”这样的经典语录都会脱口而出,其实从本质上来讲,都没有错,但这样的说法太缥缈&…

基于CPS-SPWM链式STATCOM系统在电压不平衡环境下控制策略的simulink建模与仿真

目录 1.课题概述 2.系统仿真结果 3.核心程序与模型 4.系统原理简介 5.完整工程文件 1.课题概述 基于CPS-SPWM链式STATCOM系统在电压不平衡环境下控制策略的simulink建模与仿真。利用电压外环PI调节器得到有功 电流指令值结合由负载侧电流检测 到 的无功 电流指令值 &#…

element-plus表单组件之自动补全组件el-autocomplete和级联选择器组件el-cascader

el-autocomplete 自动补全组件 自补全组件的功能和可以根据输入过滤的el-select组件有些类似。 fetch-suggestions 根据输入框的输入获取建议的内容,其接受值是一个函数,有2个参数,querystring:输入的内容,callback内置函数&…

C 语言连接MySQL 数据库

前提条件 本机安装MySQL 8 数据库 整体步骤 第一步:开启Windows 子系统安装Ubuntu 22.04.4,安装MySQL 数据库第三方库执行 如下命令: sudo aptitude install libmysqlclient-dev wz2012LAPTOP-8R0KHL88:/mnt/e/vsCode/cpro$ sudo aptit…

【论文阅读】AttnDreamBooth | 面向文本对齐的个性化图片生成

文章目录 1 动机2 方法3 实验 1 动机 使用灵活的文本控制可以实现一些特定的概念的注入从而实现个性化的图片生成。 最经典的比如一些好玩的动漫人物的概念,SD大模型本身是不知道这些概念的,但是通过概念注入是可以实现的从而生成对应的动漫人物 两个…

使用Java Spring Boot生成二维码与条形码

个人名片 🎓作者简介:java领域优质创作者 🌐个人主页:码农阿豪 📞工作室:新空间代码工作室(提供各种软件服务) 💌个人邮箱:[2435024119qq.com] &#x1f4f1…

【分布式计算】java消息队列机制

消息队列是一种在不同组件或应用之间进行数据传递的技术,通常用于处理异步通信。它允许消息的发送者(生产者)和接收者(消费者)之间进行解耦。 概念 消息队列是一种先进先出(FIFO)的数据结构&…

(三十九)Vue之集中式的状态管理机制Vuex

目录 概念vuex的核心概念State(状态)Getters(获取器)Mutations(突变)Actions(动作) 搭建vuex环境基本使用getters的使用 上一篇:(三十八)Vue之插槽…

02 设计过程概述

02 设计过程概述 2-1 设计需求2-2 飞机设计的各个阶段2-2-1 概念设计2-2-2 初步设计2-2-3 详细设计 2-3 飞机概念设计的流程2-4 集成产品开发和飞机设计2-5 补充2-5-1 布局设计(Configuration Design)关键任务:作用和重要性:使用领…

SinoDB导入导出工具汇总

在进行数据迁移、数据库表备份、表重建以及批量数据加载时,我们经常希望数据处理过程能够更快点。本文是SinoDB导入导出工具的汇总,大家可以根据不同场景选择合适的SinoDB导入导出工具。 1. 各工具特点 通常利用dbschema工具导出数据库结构,…