类
面向对象编程(object-oriented programming)时最有效的软件编写方法之一。在面向对象编程中,你将编写表示现实世界中的事物和情景的类(class),并基于这些类来创建对象(object)
根据类来创建对象称为实例化,这让你能够使用类的实例(instance)
创建和使用类
创建Dog类
class Dog"
"""一次模拟小狗的简单尝试"""
def _init_(self,name,age):
"""初始化属性name和age"""
self.name=name
self.age=age
def sit(self):
"""模拟小狗收到命令坐下"""
print(f"{self.name} is noe sitting.")
def roll_over(self):
"""模拟小狗收到命令时打滚"""
print(f"{self.name} rolled over!")
__init__()是一个特殊的方法,每当你根据Dog类创建实例时,Python都会运行它。这个方法的开头和末尾都有下划线(各双下划线),旨在避免Python默认方法与普通方法发生名称冲突。务必确保两边都有下划线,否则当你使用类创建实例时,将不会自动调用这个方法,进而引发难以发现的错误
定义形参self,实参self会自动传入,该实参是一个指向实例本身的引用,让实例能够访问类中的属性和方法
可通过实例访问的变量称为属性(attribute),java里叫做成员变量
根据类创建实例
my_dog=Dog('Willie',6)
命名约定:首字母大写为类,全小写为实例
1.访问属性
my_dog.name
2.调用方法
my_dog.sit()
3.创建多个实例
my_dog=Dog('Willie',6)
your_dog=Dog('Lucy',3)
使用类和实例
Car类
class Car:
"""一次汽车模拟的简单尝试"""
def __init__(self,make,model,year):
self.make=make
self.model=model
self.year=year
def get_descriptive_name(self):
"""返回格式规范的描述性信息"""
long_name=f"{self.year}{self.make}{self.model}"
return long_name.title()
my_new_car=Car("audi","a4",2024)
print(my_new_car.get_descriptive_name())
给属性指定默认值
有些属性无需通过形参来定义,可以在__init__()方法中指定默认值
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_reading(self):
"""打印一条指出汽车行驶里程的信息"""
print(f"This car has {self.odometer_reading} miles on it.")
my_new_car=Car("audi","a4",2024)
print(my_new_car.get_descriptive_name())
my_new_car.read_odometer_reading()
修改属性的值
三种方法:直接通过实例修改,通过方法设置,以及通过方法递增(增加特定的值)
1.直接修改属性的值
my_new_car.odometer_reading=23
2.通过方法修改属性的值
def update_odometer(self,mileage):
"""将里程表读数设置为指定的值"""
self.odometer_reading=mileage
my_new_car=Car("audi","a4",2024)
my_new_car.update_odometer(23)
def update_odometer(self,mileage):
"""将里程表读数设置为指定的值
禁止将里程表读数回调"""
if(mileage>=self.odometer_reading):
self.odometer_reading=mileage
else:
print("can't roll back")
还可以添加一些逻辑,禁止回调里程数
3.通过方法让属性的值递增
def increment_odometer(self,miles):
"""让里程数添加指定的量"""
self.odometer_reading+=miles
继承
在编写类时,并非要总是从头开始。如果要编写的类是一个既有类的特殊版本,可以使用继承(inheritance),当一个类继承另一个类时,将自动获得后者的所有属性和方法。原有的类称为父类,而新类称为子类
子类的_init_()方法
创建 子类时,父类必须包含在当前文件中,且位于子类前面
定义子类时,必须在括号内指定父类的名称
__init__()方法接受创建Car实例所需的信息
super()是一个特殊的函数,让你能够调用父类的方法。这行代码让Python调用Car类的__init__()方法,从而让ElectricCar实例包含这个方法定义的所有属性。父类也称为超类(superclass)
class Car:
----
class ElectricCar(Car):
"""电动汽车的独特之处"""
def __init__(self, make, model, year):
"""初始化父类的属性"""
super().__init__(make, model, year)
my_leaf=ElectricCar('nissan','leaf',2024)
print(my_leaf.get_descriptive_name())
在Python中,子类继承父类的方法是通过以下两种方式实现的:
- ElectricCar(Car) :这是类定义时的继承声明,表示 ElectricCar 类将继承 Car 类的所有属性和方法。这是继承的基础。
- super().init(make, model, year) :这是显式调用父类的构造函数,确保父类的初始化逻辑被执行。 super() 函数返回父类的实例, init 是父类的构造函数。
在你的代码中:
- ElectricCar(Car) 声明了继承关系,使 ElectricCar 可以访问 Car 的所有方法,包括 get_descriptive_name 。
- super().init(make, model, year) 确保父类 Car 的构造函数被调用,从而正确初始化 make 、 model 和 year 属性。
因此, get_descriptive_name 方法是通过 ElectricCar(Car) 继承到子类的,而 super() 的作用是确保父类的初始化逻辑被执行。
给子类定义属性和方法
让一个类继承另一个类后,就可以添加区分子类和父类的所需的新属性和新方法
class ElectricCar(Car):
"""电动汽车的独特之处"""
def __init__(self, make, model, year):
"""初始化父类的属性"""
super().__init__(make, model, year)
self.battery_size=40
def descrbe_battery(self):
"""打印一条描述电池容量的信息"""
print(f"This car has a{self.battery_size}-kwh battery")
my_leaf=ElectricCar('nissan','leaf',2024)
print(my_leaf.get_descriptive_name())
my_leaf.descrbe_battery()
重写父类中的方法
class ElectricCar(Car):
def fill_gas_tank(self):#原本Car父类中的方法
"""电动车没有油箱"""
print("电动车没有油箱")
将实例用作属性
在代码模拟实物时,会发现自己给类添加类太多的细节:属性和方法越来越多,文件名越来越长。
可以将类的一部分提取出来,作为独立的类,将大型类拆分成多个协同的小类,这种方法称为组合
class ElectricCar(Car):
"""电动汽车的独特之处"""
def __init__(self, make, model, year):
"""初始化父类的属性"""
super().__init__(make, model, year)
self.battery=battery()
class battery():#电池被独立弄出一个类
def __init__(self,battery_size=40):
"""初始化电池的属性"""
self.battery_size=battery_size
def descrbe_battery(self):
"""打印一条描述电池容量的信息"""
print(f"This car has a{self.battery_size}-kwh battery")
my_leaf=ElectricCar('nissan','leaf',2024)
print(my_leaf.get_descriptive_name())
my_leaf.battery.descrbe_battery()
模拟实物
在编程中, 函数 和 方法 是两个相关但不同的概念:
1. 函数(Function)
-
定义 :函数是独立的代码块,可以接受输入参数并返回结果。它不依赖于任何特定的对象或类。
-
调用方式 :直接通过函数名调用。
-
示例 :
def add(a, b): return a + b result = add(3, 5) # 直接调用函数
2. 方法(Method)
-
定义 :方法是与类或对象关联的函数。它定义在类中,并且通常用于操作类的实例(对象)的数据。
-
调用方式 :通过类的实例或类本身调用。
-
示例 :
class Calculator: def add(self, a, b): # add 是一个方法 return a + b calc = Calculator() result = calc.add(3, 5) # 通过对象调用方法
主要区别 特性 函数 方法 定义位置
独立于类或对象
定义在类中 调用方式
直接调用
通过对象或类调用 参数
可以没有特定参数
通常至少有一个参数(如 self ) 作用
通用功能
操作类的数据或行为
- 函数 是独立的,不依赖于类或对象。
- 方法 是类的一部分,用于操作类的实例或类本身的数据。
导入类
Python整体理念:文件尽量简洁
允许将类存储在模块中,然后在主程序中导入所需的模块
导入单个类
car.py
"""一个用来表示汽车的类"""
class Car:
......
....
my_car.py
from car import Car
在一个模块中储存多个类
car.py
"""一个用来表示汽车的类"""
class Car:
class battery:
class ElectriCar(Car):
....
my_electric_car.py
from car import ElectriCar
从一个模块中导入多个类
my_cars.py
from car import Car,ElectriCar
my_mustang=Car('ford','mustang',2024)
导入整个模块
my_cars.py
import car
my_mustang=car.Car
点号访问所需要的类
导入模块的所有类
from module_name import * (不建议)
建议使用module_name.classname
在一个模块中导入另一个模块
electric_car.py
from car import Car
class battery:
class ElectriCar(Car):
my_cars.py
from car import Car
from car import ElectriCar
my_mustang=Car('ford','mustang',2024)
使用别名
from car import ElectriCar as EC
找到合适的工作流程
python标准库
例如
from random import randint
randint(1,6)#含左右
from random import choice
将一个列表或元组作为参数,随机返回其中的一个元素
类的编程风格
类名:驼峰命名法,首字母都大写
类定义后面紧跟文档字符串
一个空行分隔方法
两个空行分隔类