Python Day 8 2020-4-19
Python 类
创建和使用类
1.创建 Dog 类
在Python中,首字母大写的名称指的是类。
(1)方法__init__():类中的函数称为方法;前面学到的有关函数的一切都适用于方法,就目前而言,唯一重要的差别是调用方法的方式。
(2)方法__init__()是一个特殊的方法,每当你根据类创建新实例时,Python都会自动运行它。在这个方法的名称中,开头和末尾各有两个下划线,这是一种约定,旨在避免Python默认方法与普通方法发生名称冲突。
(3)以self为前缀的变量都可供类中的所有方法使用,我们还可以通过类的任何实例来访问这些变量。
class Dog():
"""一次模拟小狗的简单尝试"""
def __init__(self, name, age):
"""初始化属性name和age"""
self.name = name
self.age = age
2.根据类创建实例
(1)要访问实例的属性,可使用句点表示法。
my_dog.name
(2) 调用方法,可以使用句点表示法来调用类中定义的任何方法。
3.创建多个实例
使用类和实例
1.Car 类
2.给属性指定默认值
类中的每个属性都必须有初始值,哪怕这个值是0或空字符串。在有些情况下,如设置默认值时,在方法__init__()内指定这种初始值是可行的;如果对某个属性这样做了,就无需包含为它提供初始值的形参。
def __init__(self, make, model, year):
"""初始化描述汽车的属性"""
self.make = make
self.model = model
self.year = year
self.odometer_reading = 0
3.修改属性的值
(1)直接修改属性的值
要修改属性的值,最简单的方式是通过实例直接访问它。
my_new_car.odometer_reading = 23
(2)通过方法修改属性的值
无需直接访问属性,而可将值传递给一个方法,由它在内部进行更新。
def update_odometer(self, mileage):
"""将里程表读数设置为指定的值"""
self.odometer_reading = mileage
(3)通过方法对属性的值进行递增
def increment_odometer(self, miles):
"""将里程表读数增加指定的量"""
self.odometer_reading += miles
继承
一个类继承另一个类时,它将自动获得另一个类的所有属性和方法;原有的类称为父类,而新类称为子类。子类继承了其父类的所有属性和方法,同时还可以定义自己的属性和方法。
1.子类的方法__init__()
创建子类的实例时,Python首先需要完成的任务是给父类的所有属性赋值。
super()是一个特殊函数,帮助Python将父类和子类关联起来。
def __init__(self, make, model, year):
"""初始化父类的属性"""
super().__init__(make, model, year)
2.给子类定义属性和方法
一个类继承另一个类后,可添加区分子类和父类所需的新属性和方法。
def __init__(self, make, model, year):
"""
电动汽车的独特之处
初始化父类的属性,再初始化电动汽车特有的属性
"""
super().__init__(make, model, year)
self.battery_size = 70
3.重写父类的方法
对于父类的方法,只要它不符合子类模拟的实物的行为,都可对其进行重写。可在子类中定义一个这样的方法,即它与要重写的父类方法同名。这样,Python将不会考虑这个父类方法,而只关注你在子类中定义的相应方法。
4.将实例用作属性
将类的一部分作为一个独立的类提取出来。可以将大型类拆分成多个协同工作的小类。
class Battery():
"""一次模拟电动汽车电瓶的简单尝试"""
def __init__(self, battery_size=70):
"""初始化电瓶的属性"""
self.battery_size = battery_size
def describe_battery(self):
"""打印一条描述电瓶容量的消息"""
print("This car has a " + str(self.battery_size) + "-kWh battery.")
导入类
1.导入单个类
from car import Car
2.在一个模块中存储多个类
from car import ElectricCar
3.从一个模块中导入多个类
从一个模块中导入多个类时,用逗号分隔了各个类。
from car import Car, ElectricCar
4.导入整个模块
可以导入整个模块,再使用句点表示法访问需要的类。
import car
5.导入模块中的所有类
要导入模块中的每个类,可使用下面的语法:
from module_name import *
5.在一个模块中导入另一个模块
有时候,需要将类分散到多个模块中,以免模块太大,或在同一个模块中存储不相关的类。将类存储在多个模块中时,你可能会发现一个模块中的类依赖于另一个模块中的类。在这种情况下,可在前一个模块中导入必要的类。
from car import Car
class Battery():
--snip--
class ElectricCar(Car):
--snip--
from car import Car
from electric_car import ElectricCar
Python 标准库
1.可使用标准库中的任何函数和类,为此只需在程序开
头包含一条简单的import语句。
2.模块collections中的一个类——OrderedDict
3.要创建字典并记录其中的键—值对的添加顺序,可使用模块collections中的OrderedDict类。OrderedDict实例的行为几乎与字典相同,区别只在于记录了键—值对的添加顺序。
from collections import OrderedDict
favorite_languages = OrderedDict()
4.模块 random 包含以各种方式生成随机数的函数,其中的 randint()返回一个位于指定范围内的整数。
类编码风格
1.类名应采用驼峰命名法,即将类名中的每个单词的首字母都大写,而不使用下划线。实例名和模块名都采用小写格式,并在单词之间加上下划线。
2.对于每个类,都应紧跟在类定义后面包含一个文档字符串。这种文档字符串简要地描述类的功能,并遵循编写函数的文档字符串时采用的格式约定。每个模块也都应包含一个文档字符串,对其中的类可用于做什么进行描述。
3.可使用空行来组织代码,但不要滥用。在类中,可使用一个空行来分隔方法;而在模块中,可使用两个空行来分隔类。
4.需要同时导入标准库中的模块和你编写的模块时,先编写导入标准库模块的import语句,再添加一个空行,然后编写导入你自己编写的模块的import语句。在包含多条import语句的程序中,这种做法让人更容易明白程序使用的各个模块都来自何方。
课后习题
9-1 餐馆:创建一个名为 Restaurant 的类,其方法__init__()设置两个属性:restaurant_name 和cuisine_type。创建一个名为 describe_restaurant()的方法和一个名为 open_restaurant()的方法,其中前者打印前述两项信息,而后者打印一条消息,指出餐馆正在营业。根据这个类创建一个名为 restaurant 的实例,分别打印其两个属性,再调用前述两个方法。
9-2 三家餐馆:根据你为完成练习 9-1 而编写的类创建三个实例,并对每个实例调用方法 describe_restaurant()。
9-3 用户:创建一个名为 User 的类,其中包含属性 first_name 和 last_name,还有用户简介通常会存储的其他几个属性。在类 User 中定义一个名为 describe_user()的方法,它打印用户信息摘要;再定义一个名为 greet_user()的方法,它向用户发出个性化的问候。创建多个表示不同用户的实例,并对每个实例都调用上述两个方法。
9-4 就餐人数:在为完成练习 9-1 而编写的程序中,添加一个名为 number_served的属性,并将其默认值设置为 0。根据这个类创建一个名为 restaurant 的实例;打印有多少人在这家餐馆就餐过,然后修改这个值并再次打印它。
添加一个名为 set_number_served()的方法,它让你能够设置就餐人数。调用这个方法并向它传递一个值,然后再次打印这个值。
添加一个名为 increment_number_served()的方法,它让你能够将就餐人数递增。调用这个方法并向它传递一个这样的值:你认为这家餐馆每天可能接待的就餐人数。
9-5 尝试登录次数:在为完成练习 9-3 而编写的 User 类中,添加一个名为login_attempts 的属性。
编写一个名为increment_login_attempts()的方法,它将属性login_attempts 的值加 1。再编写一个名为reset_login_attempts()的方法,它将属性login_attempts 的值重置为 0。
根据 User 类创建一个实例,再调用方法 increment_login_attempts()多次。打印属性 login_attempts 的值,确认它被正确地递增;然后,调用方法 reset_login_attempts(),并再次打印属性 login_attempts 的值,确认它被重置为 0。
9-6 冰淇淋小店:冰淇淋小店是一种特殊的餐馆。编写一个名为 IceCreamStand 的类,让它继承你为完成练习 9-1 或练习 9-4 而编写的 Restaurant 类。这两个版本的Restaurant 类都可以,挑选你更喜欢的那个即可。添加一个名为 flavors 的属性,用于
存储一个由各种口味的冰淇淋组成的列表。编写一个显示这些冰淇淋的方法。创建一个IceCreamStand 实例,并调用这个方法。
9-7 管理员:管理员是一种特殊的用户。编写一个名为 Admin 的类,让它继承你为完成练习 9-3 或练习 9-5 而编写的 User 类。添加一个名为 privileges 的属性,用于存储一个由字符串(如"can add post"、“can delete post”、"can ban user"等)组成的列表。编写一个名为 show_privileges()的方法,它显示管理员的权限。创建一个 Admin实例,并调用这个方法。
9-8 权限:编写一个名为 Privileges 的类,它只有一个属性——privileges,其中存储了练习 9-7 所说的字符串列表。将方法 show_privileges()移到这个类中。在 Admin类中,将一个 Privileges 实例用作其属性。创建一个 Admin 实例,并使用方法
show_privileges()来显示其权限。
9-9 电瓶升级:在本节最后一个 electric_car.py 版本中,给 Battery 类添加一个名为upgrade_battery()的方法。这个方法检查电瓶容量,如果它不是 85,就将它设置为 85。创建一辆电瓶容量为默认值的电动汽车,调用方法 get_range(),然后对电瓶进行升级,并再次调用 get_range()。你会看到这辆汽车的续航里程增加了。
9-10 导入 Restaurant 类:将最新的 Restaurant 类存储在一个模块中。在另一个文件中,导入 Restaurant 类,创建一个 Restaurant 实例,并调用 Restaurant 的一个方法,以确认 import 语句正确无误。
9-11 导入 Admin 类:以为完成练习 9-8 而做的工作为基础,将 User、Privileges 和Admin 类存储在一个模块中,再创建一个文件,在其中创建一个 Admin 实例并对其调用方法 show_privileges(),以确认一切都能正确地运行。
9-12 多个模块:将 User 类存储在一个模块中,并将 Privileges 和 Admin 类存储在另一个模块中。再创建一个文件,在其中创建一个 Admin 实例,并对其调用方法show_privileges(),以确认一切都依然能够正确地运行。
9-13 使用 OrderedDict:在练习 6-4 中,你使用了一个标准字典来表示词汇表。请使用 OrderedDict 类来重写这个程序,并确认输出的顺序与你在字典中添加键—值对的顺序一致。
9-14 骰子:模块 random 包含以各种方式生成随机数的函数,其中的 randint()返回一个位于指定范围内的整数,
例如,下面的代码返回一个 1~6 内的整数:
from random import randint
x = randint(1, 6)
请创建一个 Die 类,它包含一个名为 sides 的属性,该属性的默认值为 6。编写一个名为 roll_die()的方法,它打印位于 1 和骰子面数之间的随机数。创建一个 6 面的骰子,再掷 10 次。创建一个 10 面的骰子和一个 20 面的骰子,并将它们都掷 10 次。
9-15 Python Module of the Week:要了解 Python 标准库,一个很不错的资源是网站 Python Module of the Week。请访问 http://pymotw.com/并查看其中的目录,在其中找一个你感兴趣的模块进行探索,或阅读模块 collections 和 random 的文档。
# -*- coding: GBK -*-
from collections import OrderedDict
from random import randint
#9-1
class Restaurant():
def __init__(self,restaurant_name,cuisine_type):
self.restaurant_name=restaurant_name
self.cuisine_type=cuisine_type
self.number_served=0
def describe_restaurant(self):
print('restaurant_name:'+self.restaurant_name)
print('cuisine_type:'+self.cuisine_type)
def open_restaurant(self):
print('The restaurant is open!')
def set_number_served(self,message):
self.number_served=message
def increment_number_served(self,message):
self.number_served+=message
restaurant = Restaurant('love honey','nana')
print('The restaurant name is:'+restaurant.restaurant_name.title())
print('The restaurant cuisine_type is:'+restaurant.cuisine_type.upper())
restaurant.describe_restaurant()
restaurant.open_restaurant()
#9-2
restaurant1 = Restaurant('honey','na')
restaurant1.describe_restaurant()
restaurant2 = Restaurant('love','nn')
restaurant2.describe_restaurant()
#9-3
class User():
def __init__(self,first_name,last_name,age,hobby):
self.first_name=first_name
self.last_name=last_name
self.age=age
self.hobby=hobby
self.login_attempts=1
def describe_user(self):
print('first_name:'+self.first_name)
print('last_name:'+self.last_name)
print('age:'+str(self.age))
print('hobby:'+self.hobby)
def greet_user(self):
print('You are welcome to join us!'+'\n')
def increment_login_attempts(self):
self.login_attempts+=1
def reset_login_attempts(self):
self.login_attempts=0
user = User('D','XN',20,'music')
user.describe_user()
user.greet_user()
user1 = User('Z','QY',22,'dance')
user1.describe_user()
user1.greet_user()
user2 = User('W','HQ',20,'tourism')
user2.describe_user()
user2.greet_user()
#9-4
restaurant=Restaurant('love honey','nana')
print('Number of people eating today:'+str(restaurant.number_served))
restaurant.number_served=20
print('Number of people eating today:'+str(restaurant.number_served))
restaurant.set_number_served(30)
print('Number of people eating today:'+str(restaurant.number_served))
restaurant.increment_number_served(5)
print('Number of people eating today:'+str(restaurant.number_served))
#9-5
user3=User('D','XN',20,'music')
user3.increment_login_attempts()
print('login_attempts:'+str(user3.login_attempts))
user3.increment_login_attempts()
print('login_attempts:'+str(user3.login_attempts))
user3.increment_login_attempts()
print('login_attempts:'+str(user3.login_attempts))
user3.reset_login_attempts()
print('login_attempts:'+str(user3.login_attempts))
#9-6
class IceCreamStand(Restaurant):
def __init__(self,restaurant_name,cuisine_type):
super().__init__(restaurant_name,cuisine_type)
self.flavors=['chocolate','vanilla','strawberry']
def showflavors(self):
print('IceCream flavors:')
for flavor in self.flavors:
print(flavor)
icecreamStand=IceCreamStand('honey','na')
icecreamStand.showflavors()
#9-7
class Admin(User):
def __init__(self,first_name,last_name,age,hobby):
super().__init__(first_name,last_name,age,hobby)
self.privileges=Privileges()
self.privileges=['can add post','can delete post','can ban user']
def show_privileges(self):
print('The administrator permission is:')
for privilege in self.privileges:
print('\t'+privilege)
admin=Admin('D','XN',20,'music')
admin.show_privileges()
#9-8
class Privileges():
def __init__(self,privileges=['can add post',
'can delete post',
'can ban user']):
self.privileges=privileges
def show_privileges(self):
print('The administrator permission is:')
for privilege in self.privileges:
print('\t'+privilege)
admin=Admin('D','XN',20,'music')
admin.privileges.show_privileges()
#9-9~12略
#9-13
words=OrderedDict()
words['append()']='在列表尾添加元素'
words['insert()']='在列表中插入元素'
words['del']='将值从列表中删除'
words['pop()']='删除列表末尾的元素'
words['remove()']='根据值删除元素'
words['sort()']='对列表进行永久性排序'
words['sorted()']='对列表进行保留性排序'
words['reverse()']='对列表进行反转性排序'
words['len()']='确定列表的长度'
words['range()']='创建数字列表'
for key,value in words.items():
print("\n"+key+":"+value)
#9-14
class Die():
def __init__(self,sides=6):
self.sides=sides
def roll_die(self):
print(randint(1,self.sides))
die=Die()
die.roll_die()
die.roll_die()
die.roll_die()
die.roll_die()
die.roll_die()
die.roll_die()
die.roll_die()
die.roll_die()
die.roll_die()
die.roll_die()
print('\n')
die=Die(10)
die.roll_die()
die.roll_die()
die.roll_die()
die.roll_die()
die.roll_die()
die.roll_die()
die.roll_die()
die.roll_die()
die.roll_die()
die.roll_die()
print('\n')
die=Die(20)
die.roll_die()
die.roll_die()
die.roll_die()
die.roll_die()
die.roll_die()
die.roll_die()
die.roll_die()
die.roll_die()
die.roll_die()
die.roll_die()
print('\n')