第九章 类
- 创建和使用类
- 在定义类时,以首字母大写的指定为类
- 类中的函数称之为方法,其定义与函数相同,唯独在调用方式上有所差别
- 类中的默认方法的定义需要左右加"__",旨在避免与普通方法发生命名冲突
- 每个与类相关联的方法都将自动传递实参selfm,它是一个指向实例本身的引用,让实例能够访问类中的属性和方法
- 以self为前缀的变量可供类中的所有方法使用,也可供实例访问,像这样的变量称之为属性
01 class Dog(): 02 """一次模拟小狗的简单尝试""" 03 def __init__(self, name, age): 04 """初始化属性name和age""" 05 self.name = name 06 self.age = age 07 def sit(self): 08 """模拟小狗被命令时蹲下""" 09 print(self.name.title() + " is now sitting.") 10 def roll_over(self): 11 """模拟小狗被命令时打滚""" 12 print(self.name.title() + " rolled over!") 13 14 15 my_dog=Dog('Willie',6); 16 print("my dog's name is "+my_dog.name.title()+"."); 17 print("my dogis "+str(my_dog.age)+" years old."); 18 my_dog.sit(); 19 my_dog.roll_over(); >>> my dog's name is Willie. my dogis 6 years old. Willie is now sitting. Willie rolled over! |
- 使用类和实例
修改属性值的两种方法:
- 直接修改属性值
- 通过方法修改属性的值
01 class Car(): 02 """这是一个关于汽车的类""" 03 def __init__(self,make,model,year): 04 self.make=make; 05 self.model=model; 06 self.year=year; 07 self.odometer_reading=0 08 def get_descriptive_name(self): 09 """返回整洁的描述性信息""" 10 long_name=str(self.year)+' '+self.make+' '+self.model; 11 return long_name.title() 12 def read_odometer(self): 13 """打印一条指向汽车里程的消息""" 14 print("This car has "+str(self.odometer_reading)+" miles on it"); 15 def update_odometer(self,mileage): 16 """将里程表读数设定为指定值""" 17 self.odometer_reading=mileage; 18 19 # 使用默认值 20 my_new_car=Car('audi','a4',2016); 21 print(my_new_car.get_descriptive_name()); 22 my_new_car.read_odometer(); 23 # 直接修改属性值 24 my_new_car.odometer_reading=23; 25 my_new_car.read_odometer(); 26 # 通过方法修改属性值 27 my_new_car.update_odometer(108); 28 my_new_car.read_odometer(); >>> 2016 Audi A4 This car has 0 miles on it This car has 23 miles on it This car has 108 miles on it |
- 类的继承
注意:
- 创建子类时, 父类必须包含在当前文件中, 且位于子类前面
- 定义子类时, 必须在括号内指定父类的名称。 方法__init__() 接受创建Car 实例所需的信息
- super() 是一个特殊函数, 帮助Python将父类和子类关联起来。让ElectricCar 实例包含父类的所有属性。 父类也称为超类 (superclass) , 名称super因此而得名。
01 class Car(): 02 """这是一个关于汽车的类""" 03 def __init__(self,make,model,year): 04 self.make=make; 05 self.model=model; 06 self.year=year; 07 self.odometer_reading=0 08 def get_descriptive_name(self): 09 """返回整洁的描述性信息""" 10 long_name=str(self.year)+' '+self.make+' '+self.model; 11 return long_name.title() 12 def read_odometer(self): 13 """打印一条指向汽车里程的消息""" 14 print("This car has "+str(self.odometer_reading)+" miles on it"); 15 def update_odometer(self,mileage): 16 """将里程表读数设定为指定值""" 17 self.odometer_reading=mileage; 18 19 class ElectricCar(Car): 20 """Represent aspects of a car,specific to electric vehicles""" 21 def __init__(self,make,model,year): 22 """ 23 电动汽车的独特之处 24 初始化父类属性,再初始化电动汽车的特有属性 25 """ 26 super().__init__(make,model,year) 27 self.battery_size=70 28 29 def describe_battery(self): 30 """打印一条描述电瓶容量的消息""" 31 print("This car has a "+str(self.battery_size)+"- kwh battery."); 32 33 34 my_tesla=ElectricCar('Tesla','model s',2016); 35 print(my_tesla.get_descriptive_name()); 36 my_tesla.describe_battery(); >>> 2016 Tesla Model S This car has a 70- kwh battery. |
- 类的重写:在子类中重新定义一个与父类方法同名的方法进行覆盖即可
- 将类用作另外一个类中的属性
01 class Car(): 02 """这是一个关于汽车的类""" 03 def __init__(self,make,model,year): 04 self.make=make; 05 self.model=model; 06 self.year=year; 07 self.odometer_reading=0 08 def get_descriptive_name(self): 09 """返回整洁的描述性信息""" 10 long_name=str(self.year)+' '+self.make+' '+self.model; 11 return long_name.title() 12 def read_odometer(self): 13 """打印一条指向汽车里程的消息""" 14 print("This car has "+str(self.odometer_reading)+" miles on it"); 15 def update_odometer(self,mileage): 16 """将里程表读数设定为指定值""" 17 self.odometer_reading=mileage; 18 19 class Battery(): 20 """一次模拟电动汽车的简单尝试""" 21 def __init__(self,battery_size=70): 22 """初始化电池属性""" 23 self.battery_size=battery_size; 24 def describe_battery(self): 25 """打印一条描述电瓶容量的信息""" 26 print("This car has a "+str(self.battery_size)+"-kwh battery."); 27 28 class ElectricCar(Car): 29 """Represent aspects of a car,specific to electric vehicles""" 30 def __init__(self,make,model,year): 31 """ 32 电动汽车的独特之处 33 初始化父类属性,再初始化电动汽车的特有属性 34 """ 35 super().__init__(make,model,year) 36 self.battery=Battery();# 在一个类中引用另一个类 37 38 def describe_battery(self): 39 """打印一条描述电瓶容量的消息""" 40 print("This car has a "+str(self.battery_size)+"- kwh battery."); 41 # 覆盖Car类的方法 42 def read_odometer(self): 43 print("This car has "+str(self.odometer_reading)+" m on it"); 44 45 46 my_tesla=ElectricCar('Tesla','model s',2016); 47 print(my_tesla.get_descriptive_name()); 48 my_tesla.battery.describe_battery(); >>> 2016 Tesla Model S This car has a 70-kwh battery. |
- 类的导入
在将类模块文件后,在使用该类的其他文件中使用该类时,必须从存有类的文件中将其引用(假设存储类在car.py中)
01 from car import Car 02 my_new_car = Car('audi', 'a4', 2016) 03 print(my_new_car.get_descriptive_name()) 04 my_new_car.odometer_reading = 23 05 my_new_car.read_odometer() >>> 2016 Audi A4 This car has 23 miles on it. |
其他导入模块的方法与导入函数相似,主要包括:在一个模块中存储多个类,在一个模块中导入多个类,导入整个模块(*导入类较多时推荐),导入模块中的所有类,一个模块中导入另外一个模块。P89-P90
- Python标准库
介绍标准库中的两个类:
- 创建字典并记录其中的键—值对的添加顺序, 可使用模块collections 中的OrderedDict
- 模块random 包含以各种方式生成随机数的函数, 其中的randint() 返回一个位于指定范围内的整数
01 from collections import OrderedDict 02 03 favorite_languages = OrderedDict() 04 favorite_languages['jen'] = 'python' 05 favorite_languages['sarah'] = 'c' 06 favorite_languages['edward'] = 'ruby' 07 favorite_languages['phil'] = 'python' 08 for name,language in favorite_languages.items(): 09 print(name.title() + "'s favorite language is " + 10 language.title() + ".") >>> Jen's favorite language is Python. Sarah's favorite language is C. Edward's favorite language is Ruby. Phil's favorite language is Python. |
- *类编码风格:
- 类名应采用驼峰命名法 , 即将类名中的每个单词的首字母都大写, 而不使用下划线。 实例名和模块名都采用小写格式, 并在单词之间加上下划线
- 对于每个类(模块), 都应紧跟在类(模块)定义后面包含一个文档字符串。 这种文档字符串简要地描述类的功能。
- 可使用空行来组织代码, 但不要滥用。 在类中, 可使用一个空行来分隔方法; 而在模块中, 可使用两个空行来分隔类。
- 先编写导入标准库模块的import 语句, 再添加一个空行, 然后编写导入你自己编写的模块的import 语句。