初识Python必看基础知识~ 续(5)进阶之路~再接再厉~


欢迎来到~ 初始Python 系列文章 “第五回”,大家好呀~ 我是 清汉
在这里插入图片描述


不知不觉中已是Python基础系列中的第五篇文章了~

Python基础系列,每篇文章的篇幅都比较长、比较详细、比较啰嗦~

力求让每一个初学Python的人或者没有接触过编程的人,都能看得明白、看的真切。

从而产生对编程的兴趣,步入这个神奇的领域,了解计算机的世界,开拓不同维度的世界观~

注:下图截取于B站,附传送门:计算机科学速成课
有兴趣的小伙伴可以看一下,一个很棒的系列短视频,相信我,会让你爱上计算机的~

在这里插入图片描述

接上回书~

本篇文章主角是Python中的先生

下面我们开始讲,先生的“人生海海”~

上码🐎,开始走码🐎观花~


DIY 5

声明:未打广告,全文知识梳理来源于《Python编程 从入门到实践(第2版)》豆瓣评分9.3

注:例中所有 >>> 符号后为输出结果

- -snip- - 为代码省略位置



知识框图

关于整个python基础的知识脑图


第9章

  • 面向对象编程中编写表现现实世界中的事物和情景的类,基于这些类来创建对象。
  • 编写类时,定义的一大类对象都有通用行为。基于类创建对象时,每个对象都自动具备这种通用行为,然后可根据需要,赋予每个对象独特的个性。
  • 根据类创建对象称为实例化,这让你能够使用类的实例。

是不是已经有点看迷糊了,哈哈~


在这里插入图片描述


说实话我只看这几句话,也不能理解透彻。不过文章后面的 栗子 大家吃了应该可以理解了。


这是一张关于举例子的表情包


在这里插入图片描述


创建类及实例

例1

创建类
  • 使用关键字class 定义,根据约定,Python中首字母大写的名称指的是
方法
  • 中的函数称为方法

  • 方法__init__是一个特殊的方法,当你根据创建新实例时,Python都会自动运行它。

    注意:__init__开头和结尾都有两个下划线。

  • 方法中的形参self必不可少,必须位于其他形参前面。

  • Python调用方法创建实例时,将自动传入实参self。每个实例相关联的方法调用都自动传入实参self,它是指向实例本身的引用,让实例能够访问类中的属性和方法。

  • self为前缀的变量可供中的所有方法使用,可通过的任何实例来访问。

属性
  • 可通过实例访问的变量称为 属性
创建实例
  • 例 1中具体演示了如何:
    • 创建实例
    • 访问属性
    • 调用方法
	# 例 1
# 创建 Dog 类

#这个类定义中没有圆括号(参数),因为要从空白(首个)创建这个类。
class Dog:
    '''一次模拟小狗的简单尝试'''
    def __init__(self, name, age): # 形参 name, age 分别接受小狗的名字和年龄
        '''初始化属性 name 和 age'''
        self.name = name # 将两个形参值分别赋值给以self为前缀的变量,供类中的所有方法使用
        self.age = age

    def sit(self):
        '''模拟小狗收到命令后蹲下'''
        print(f"{self.name} is now sitting.")

    def roll_over(self):
        '''模拟小狗收到命令后打滚'''
        print(f"{self.name} rolled over!")

#创建表示一个表示特定小狗的实例
my_dog = Dog('willie', 6) # 变量名 = 类名称(小狗姓名,小狗年龄)

# 访问属性
#Python先找到实例my_dog,再查找到与实例相关联的属性name,在Dog类中引用这个属性时,使用的是self.name
print(f"My dog's name is {my_dog.name}.")
# >>> My dog's name is willie.
print(f"My dog's is {my_dog.age} years old.") # my_dog.age ,同上
# >>> My dog's is 6 years old.

#调用方法,指定实例的名称和调用的方法,用 .句点分隔
my_dog.sit()  # Python在类Dog中查找方法sit()并运行其代码。
# >>> willie is now sitting.
my_dog.roll_over()
# >>> willie rolled over!

#创建多个实例
#即使第二条小狗指定同样的名字、年龄,Python依然会根据Dog类创建另一个实例。每个实例存储在不同的变量中。
your_dog = Dog('Lucy', 3)
print(f"\nMy dog's name is {your_dog.name}.")
print(f"My dog's is {your_dog.age} years old.")
your_dog.sit()
your_dog.roll_over()
# >>> My dog's name is Lucy.
# >>> My dog's is 3 years old.
# >>> Lucy is now sitting.
# >>> Lucy rolled over!

使用类及实例

例 2

  • 主要加深了对的应用,分别针对以下几点展开演示:
    • 除形参外添加新的属性,并给属性设置默认值。
    • 修改属性的值
      • 通过实例访问属性,直接修改属性的值。
      • 通过实例调用方法,修改属性的值。
	# 例 2
# car类
class Car:
    '''一次模拟汽车的简单尝试'''

    def __init__(self, make, model, year): # 形参 make, model, year 分别是汽车的品牌,型号,年份
        '''初始化描述汽车的属性'''
        self.make = make # 将三个形参值分别赋值给以self为前缀的变量,供类中的所有方法使用
        self.model = model
        self.year = year
        #添加一个属性存储汽车的里程,默认值指定为 0
        self.odometer_reading = 0

    def get_descriptive_name(self):
        '''返回整洁的描述信息'''
        long_name = f"{self.year} {self.make} {self.model}" # 将汽车的所有属性转换为字符串赋值给变量 long_name
        return long_name.title() # return 返回变量 long_name 并使用title()将字符串首字母大写

    def read_odometer(self):
        '''打印一条汽车里程的消息'''
        print(f"This car has {self.odometer_reading} miles on it.\n")
        
    # 通过方法修改属性值
    def update_odometer(self, mileage): # 形参 mileage 作为要修改的里程
        '''
        将里程表修改为指定值
        禁止将里程回调
        '''
        if mileage >= self.odometer_reading: # 如果要修改的里程大于当前里程返回True,执行if代码块
            self.odometer_reading = mileage # 将形参 mileage的值,赋值给属self.odometer_reading

        else: # 否则提示不能修改
            print("You can't roll back an odometer!")

    #通过方法对属性的值进行递增
    def increment_odmeter(self, miles): # 形参 miles 接受一个需要增加的里程数
        '''将里程增加指定的值'''
        self.odometer_reading += miles # 默认值里程数 + 需增加里程数

# 创建一个实例
my_new_car = Car('audi', 'a4', 2019) # 变量名 = 类名称(品牌,型号,年份)

print(my_new_car.get_descriptive_name()) # 调用类中的方法 get_descriptive_name(),打印汽车的描述信息
# >>> 2019 Audi A4

my_new_car.read_odometer() # 调用类中的方法 read_odometer() ,打印一条汽车里程的消息
# >>> This car has 0 miles on it.

#直接修改属性的值
my_new_car.odometer_reading = 100 # 访问类中的属性并赋值为100
my_new_car.read_odometer() # 再次调用类中的方法 read_odometer() ,打印一条汽车里程的消息
# >>> This car has 100 miles on it.

#通过方法修改属性的值
my_new_car.update_odometer(110) # 调用类中的方法 update_odometer(),并给它一个实参为110,因为需要修改的里程数大于默认值,所以允许修改,里程数变为110
my_new_car.read_odometer() # 再再次调用类中的方法 read_odometer() ,打印一条汽车里程的消息
# >>> This car has 110 miles on it.

#通过方法对属性的值进行递增
my_new_car.increment_odmeter(100) # 调用类中的方法 increment_odmeter(),给它一个实参为100,方法内执行代码里程数+100
my_new_car.read_odometer() # 再再再次调用类中的方法 read_odometer() ,打印一条汽车里程的消息
# >>> This car has 210 miles on it.

继承

例 3

  • 如果要编写的类是另一个已经存在类的特殊版本,可使用继承
  • 一个类继承另一个类时,将自动获得另一个类的所有属性和方法,同时可以定义自己的属性和方法。
  • 原有的类称为父类(也可以称为超类)
  • 新类称为子类
创建子类
  • 例3 中演示了如何创建一个子类
    • 父类必须包含在当前文件中,且位于子类前面。
    • 必须在子类的圆括号内指定父类名称。如:class 子类名称(父类名称):
    • 子类中的第一个方法__init__() 接收创建父类实例所需的信息。
    • 函数super() 让子类可以调用父类的方法。
    • 子类独有属性,父类不能使用。
    • 重写父类方法
      • 对于父类方法,只要不符合子类模拟的实物的行为,都可以重写。可在子类中定义一个与要重写父类方法同名的方法。

注:例3 前半部分代码为 例2 中的代码,之所重复引用而不是省略注明,是为了让大家方便阅读,也可以直接复制运行代码(不用分别复制)。

一个描述心细的表情包

	# 例 3
# 继承

#父类(超类)
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.\n")

    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_odmeter(self, miles):
        '''将里程增加指定的值'''
        self.odometer_reading += miles

    def fill_gas_tank(self):
        '''往油箱里装满油'''
        print('Has been filled with oil')


# 子类
class ElectricCar(Car):
    '''电动汽车的独特之处'''

    # 方法__init__() 接收创建Car实例所需的信息。
    def __init__(self, make, model, year):
        '''
        初始化父类的属性
        再初始化电动汽车特有属性
        '''
        #函数super() 让子类可以调用父类的方法。
        #让Python调用父类的方法__init__(),让子类实例包含这个方法中定义的所有属性。
        super().__init__(make, model, year)

		# 子类独有属性,父类不能使用。
        self.battery_size = 75 # 创建子类属性self.battery_size,存储电池电量

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

    #重写父类方法
    def fill_gas_tank(self):
        '''电动车无油箱'''
        print("This car doesn't need a gas thank!")

# 创建父类实例
you_tesla = Car('jipp', 'aodi', 2018)
# 创建子类实例
my_tesla = ElectricCar('tesla', 'model s', 2019)

print(my_tesla.get_descriptive_name()) # 通过子类实例,调用父类方法
# >>> 2019 Tesla Model S
my_tesla.describe_battery() # 通过子类实例调用子类实例,打印电池电量
# >>> This car has a 75-kWh battery.

my_tesla.fill_gas_tank() # 子类实例调用重写的父类方法
# >>>  This car doesn't need a gas thank!
you_tesla.fill_gas_tank() # 父类实例调用的原父类的方法
# >>>  Has been filled with oil

将实例用作属性

例 4

  • 在程序编写的过程中,随着给中添加的细节越来越多,属性和方法越来越多,代码整体显得就很臃肿。这时可以将的一部分提取出来,作为一个独立的类。将一个大类拆解成多个协同工作的小类,完成代码的重构。
  • 这里的小类并非指的是子类,而是一个新类,它没有继承任何类。
  • 例4 中演示了如何在类中创建实例并赋值到属性

注:重复内容太多,不利于阅读。若是需要复制全部代码各位少侠还是辛苦一下,去前面例中找吧~

在这里插入图片描述

	# 例 4
# 将实例用作属性
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()
#	 --snip-- 
    def fill_gas_tank(self):
        '''往油箱里装满油'''
        print('Has been filled with oil')

class ElectricCar(Car):
    '''电动汽车的独特之处'''
    def __init__(self, make, model, year):
        '''
        初始化父类的属性
        再初始化电动汽车特有属性
        '''
        super().__init__(make, model, year)
        self.battery = Battery() # 这行代码让Python创建一个新的Battery实例,因为没有指定实参默认为75
                                 # 并将该实例赋值给前面属性,因此每个ElectricCar实例都自动创建一个Battery实例
                                 
#	 --snip-- 

class Battery:
    '''一次模拟电瓶的简单尝试'''
    def __init__(self, battery_size=75): # 默认形参为 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.")


you_tesla = Car('jipp', 'aodi', 2018)
my_tesla = ElectricCar('tesla', 'model s', 2019)

print(my_tesla.get_descriptive_name())
# >>>  2019 Tesla Model S

# 先查找到属性,并对在该属性中的Battery实例调用方法describe_battery()
my_tesla.battery.describe_battery()
# >>>  This car has a 75-kWh battery.
my_tesla.battery.get_range()
# >>>  This car can go about 260 miles on a full charge.

导入类

  • 随着类中的功能越来越多,代码会变得很长,即便前边讲述了继承、拆解类等方法让代码显得不是那么臃肿,但架不住功能多啊~
  • 为遵循 Python之禅的理念,将介绍另一种方法:将不同的类存储在不同的模块中(也就单独的 .py文件中),然后在主程序中导入需要的模块。
  • 当然也可以在一个模块中也可以存放多个类。
  • 例5 中介绍模块中存储类、导入类的多种方式、方法:
    • 导入单个类
    • 在一个模块中存储多个类
    • 从一个模块中导入多个类
    • 导入整个模块
    • 导入模块中的所有类
    • 在一个模块中导入另一个模块
    • 指定类的别名
  • 上述这些,对组织大型开发项目很有好处,了解Python中提供的这些不同的方式、方法,可以让你知道那种项目组织方式是最佳的,并能理解别人开发的项目。

例 5


注:下面四个代码块分别是四个模块文件,模块名标注在每个代码块第一行。
若有兴趣想试运行代码,需将这四个代码块存放在四个 .py 文件中,且在同一文件夹下。

# 模块名称: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.\n")
        
    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_odmeter(self, miles):
        '''将里程增加指定的值'''
        self.odometer_reading += miles

class ElectricCar(Car):
    '''电动汽车的独特之处'''

    # 方法__init__() 接收创建Car实例所需的信息。
    def __init__(self, make, model, year):
        '''
        初始化父类的属性
        再初始化电动汽车特有属性
        '''
        #函数super() 让子类可以调用父类的方法。
        #让Python调用父类的方法__init__(),让子类实例包含这个方法中定义的所有属性。
        super().__init__(make, model, year)
        self.battery_size = 75 # 子类独有属性,父类不能使用。

    def describe_battery(self):
        '''打印一条描述电池电量的信息'''
        print(f"This car has a {self.battery_size}-kWh battery.")
        
    def fill_gas_tank(self):
        '''电动车无油箱'''
        print("This car doesn't need a gas thank!")
# 模块名称:electric_car.py
'''一组用于表示电动汽车的类'''
from car import Car # 模块也可嵌套,在一个模块中导入另一个模块

class ElectricCar(Car):
    '''电动汽车的独特之处'''

    # 方法__init__() 接收创建Car实例所需的信息。
    def __init__(self, make, model, year):
        '''
        初始化父类的属性
        再初始化电动汽车特有属性
        '''
        #函数super() 让子类可以调用父类的方法。
        #让Python调用父类的方法__init__(),让子类实例包含这个方法中定义的所有属性。
        super().__init__(make, model, year)
        self.battery_size = 75 # 子类独有属性,父类不能使用。

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

    #重写父类方法,子类中定义一个与要重写父类方法同名的方法。
    def fill_gas_tank(self):
        '''电动车无油箱'''
        print("This car doesn't need a gas thank!")
# 模块名称:my_car.py
#打开模块并导入类
from car import Car

my_new_car = Car('audi', 'a4', 2019)
print(my_new_car.get_descriptive_name())
# >>> 2019 Audi A4

my_new_car.odometer_reading = 23
my_new_car.read_odometer()
# >>> This car has 23 miles on it.

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

my_beetle = Car('volkswagen', 'beetle', 2019)
print(my_beetle.get_descriptive_name())
# >>> 2019 Volkswagen Beetle

my_tesla = ElectricCar('tesla', 'roadster', 2019)
print(my_tesla.get_descriptive_name())
# >>> 2019 Tesla Roadster

#导入整个模块
import car

#语法 module_name.ClassName, 模块名.类名
my_beetle = car.Car('volkswagen', 'beetle', 2018)
print(my_beetle.get_descriptive_name())
# >>> 2018 Volkswagen Beetle

my_tesla = car.ElectricCar('tesla', 'roadster', 2018)
print(my_tesla.get_descriptive_name())
# >>> 2018 Tesla Roadster
# 模块名称:my_electric_car.py
#导入模块中所有类
from car import *

my_beetle = Car('volkswagen', 'beetle', 2019)
print(my_beetle.get_descriptive_name())
# >>> 2019 Volkswagen Beetle

my_tesla = ElectricCar('tesla', 'roadster', 2019)
print(my_tesla.get_descriptive_name())
# >>> 2019 Tesla Roadster

# as 关键字指定别名
from electric_car import ElectricCar as EC

my_tesla = EC('tesla', 'roadster', 2011)
print(my_tesla.get_descriptive_name())
# >>> 2011 Tesla Roadster

本篇小结

  • 这一篇文章,虽看着多,但实际不多,多是一些重复代码,绕口了哈~,之所以多重复还是为了能够让阅读连贯、顺畅。

  • 本篇主要围绕着类进行了多方面的举例演示,希望路过的少侠看过此篇文章后,对类有了一定的了解。

  • 当然要想深入了解只看还是不行的,还是需要动手去敲~

  • 所以说学编程是个动词,自我感觉敲一遍,比看10遍都顶用。

这是一张描述学习的表情包


感谢,每一位认真阅读到这里的少侠!来个手滑三联吧,不迷路~

一张猫咪比心的表情包
关于一键三联的图片


下期见,等你哟~


在这里插入图片描述

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

清汉

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值