9.2.1 Car类
9.2.2 给属性指定默认值
9.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 = str(self.year) + ' ' + self.make + ' ' + self.model
return long_name.title()
def read_odometer(self):
"""打印指出汽车的里程信息"""
print("This car has " + str(self.odometer_reading) + " miles on it.")
def update_odometer(self, mileage):
"""设置里程表"""
self.odometer_reading = mileage
#每个与类相关联的方法 调用都自动传递实参 self
#它是一个指向实例本身的引用,让实例能够访问类中的属性和方法。
my_new_car = Car('audi', 'a4', 2019)
print(my_new_car.get_descriptive_name())
my_new_car.read_odometer()
my_new_car.odometer_reading = 23 #直接修改属性的值
my_new_car.read_odometer()
my_new_car.update_odometer(100)
my_new_car.read_odometer()
9.3 继承
9.3.1 子类的方法__init__()
9.3.2 Python 2.7中的继承
9.3.3 给子类定义属性和方法
9.3.4 重写父类的方法
9.3.5 将实例用作属性
9.3.6 模拟实物
car.py
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.")
class ElectricCar(Car):
"""电动汽车独特之处"""
def __init__(self, make, model, year):
"""初始化父类的属性"""
super().__init__(make, model, year)
self.battery_size = 70
self.battery = Battery() # 将实例用作属性
#python2.7 中的继承
#父类定义指定object
#class Car(object):
#super(ElectricCar, self).__init__(make, model, year)
def describe_battery(self):
print("This Eclectric car has a " + str(self.battery_size) + "_kWh battery.")
#重写父类方法
def get_descriptive_name(self):
long_name = str(self.year) + ' ' + self.make + ' ' + self.model + ' ' + str(self.battery_size) + 'kwh'
return long_name.title()
#我们定义了一个名为 Battery 的新类, 这看似做了很多额外的工作,但现在我们想多详细地描述电瓶都可以,且不会导致 ElectricCar
#类混乱不堪。可以再给 Battery 类添加一些方法
my_tesla = ElectricCar('tesla', 'model s', 2019)
print(my_tesla.get_descriptive_name())
my_tesla.describe_battery()
my_tesla.battery.describe_battery()
9.4 导入类
9.4.1 导入单个类
from car import Car
my_new_car = Car('audi', 'a4', 2018)
print(my_new_car.get_descriptive_name())
my_new_car.odemeter_reading = 23
my_new_car.read_odometer()
9.4.2 在一个模块中存储多个类
from car import ElectricCar
my_tesla = ElectricCar('tesla', 'model s', 2016)
my_tesla.battery.describe_battery()
9.4.3 从一个模块中导入多个类
from car import Car, ElectricCar
my_beetle = Car('volkswagen', 'beetle', 2016)
my_tesla = ElectricCar('tesla', 'roadster', 2016)
9.4.4 导入整个模块
import car
my_beetle = car.Car('volkswagen', 'beetle', 2016) 5
my_tesla = car.ElectricCar('tesla', 'roadster', 2016)
9.4.5 导入模块中的所有类
from module_name import *
不推荐, 导入类不明确, 还有可能有同名问题
需要从一个模块中导入很多类时,最好导入整个模块,并使用 module_name.class_name 语法
来访问类
9.4.6 在一个模块中导入另一个模块
#electric_car.py
from car import Car
class Battery():
-- snip --
class ElectricCar(Car):
-- snip --
#my_car.py
from car import Car #一个Car 类 单独文件
from electric_car import ElectricCar #导入car的子类
my_beetle = Car('volkswagen', 'beetle', 2016)
print(my_beetle.get_descriptive_name())
my_tesla = ElectricCar('tesla', 'roadster', 2016)
print(my_tesla.get_descriptive_name())
9.4.7 自定义工作流程
9.5 Python标准库
创建字典并记录其中的键—值对的添加顺序,可使用模块 collections 中的 OrderedDict 类
from collections import OrderedDict
favorite_languages = OrderedDict()
favorite_languages['jen'] = 'python'
favorite_languages['sarah'] = 'C'
favorite_languages['edward'] = 'ruby'
favorite_languages['phih'] = 'python'
for name, language in favorite_languages.items():
print(name.title() + "'s favorite language is " + language.title() + '.')
9.6 类编码风格
9.7 小结
10.1.1 读取整个文件
with open('pi_digit.txt') as file_object: #关键字 with 在不再需要访问文件后将其关闭
contents = file_object.read()
print(contents)
10.1.2 文件路径
linux ------ with open('text_files/ filename .txt') as file_object:
windows 反斜杠 -------with open('text_files\ filename .txt') as file_object:
10.1.3 逐行读取
with open('pi_digit.txt') as file_object:
for line in file_object:
print(line.restrip()) #restrip 要消除这些多余的空白行, 否则有每句结尾有空行
10.1.4 创建一个包含文件各行内容的列表
filename = 'pi_digit.txt'
with open(filename) as file_object:
lines = file_object.readlines()
for line in lines:
print(line.rstrip())
10.1.5 使用文件的内容
10.1.6 包含一百万位的大型文件
filename = 'pi_million_digits.txt'
with open(filename) as file_object:
lines = file_object.readlines()
pi_string = ''
for line in lines:
pi_string += line.strip()
print(pi_string[:52] + "...")
print(len(pi_string))
10.1.7 圆周率值中包含你的生日吗
10.2.1 写入空文件
10.2.2 写入多行
# r, w, a ,r+ 几种模式
filename = 'programming.txt'
with open(filename, 'w') as file_object:
file_object.write("I love programming.")
file_object.write("I love creating new games.")
10.2.3 附加到文件
如果你要给文件添加内容,而不是覆盖原有的内容,可以附加模式打开文件
open(filename, 'a')
10.3.1 处理ZeroDivisionError异常
10.3.2 使用try-except 代码块
10.3.3 使用异常避免崩溃
10.3.4 else 代码块
print("Give me two numbers, and I'll divide them.")
print("Enter 'q' to quit.")
while True:
first_number = input('\nFirst number: ')
if first_number == 'q':
break
second_number = input("Second number:")
if second_number == 'q':
break
try:
answer = int(first_number) / int(second_number)
except ZeroDivisionError:
print("You can't divide by 0!")
else:
print(answer)
10.3.5 处理FileNotFoundError异常
10.3.6 分析文本 split 函数,分割文本, 存储为列表
10.3.7 使用多个文件
def count_words(filename):
"""计算一个文件包含多少个单词"""
try:
with open(filename) as f_obj:
contents = f_obj.read()
except FileNotFoundError:
msg = "Sorry, the file " + filename + "dost not exist."
print(msg)
else:
# 计算文件大致包含多少个单词
words = contents.split()
num_words = len(words)
print("The file " + filename + " has about " + str(num_words) + " words.")
filenames = ['alice.txt', 'siddhartha.txt', 'moby_dick.txt', 'little_women.txt']
for filename in filenames:
count_words(filename)
#使用 try-except 代码块提供了两个重要的优点:避免让用户看到traceback;
#让 程 序 能 够 继 续 分 析 能 够 找 到 的 其 他 文 件
10.3.8 失败时一声不吭 pass
try:
--snip--
except FileNotFoundError:
pass
10.3.9 决定报告哪些错误
如用户输入、存在指定的文件、有网络链接,就有可能出现异常
控制与用户分享错误信息的程度
模块 json 让你能够将简单的Python数据结构转储到文件中,并在程序再次运行时加载该文件中的数据
10.4.1 使用json.dump()和json.load()
import json
numbers = [2,3,5,7,11,13]
#wirte
with open('numbers.json', 'w') as f_obj:
json.dump(numbers, f_obj)
#read
with open('numbers.json') as f_obj:
numberlist = json.load(f_obj)
print(numberlist)
10.4.2 保存和读取用户生成的数据
10.4.3 重构
import json
#如果以前存储了用户名, 就加载他
#否则,提示用户输入用户名并存储他
def get_stored_username():
"""如果存储了用户名,就获取它"""
filename = 'username.json'
try:
with open(filename) as f_obj:
username = json.load(f_obj)
except FileNotFoundError:
return None
else:
return username
def get_new_username():
"""提示用户输入用户名"""
username = input("What is your name? ")
filename = 'username.json'
with open(filename, 'w') as f_obj:
json.dump(username, f_obj)
return username
def greet_user():
"""问候用户,并指出其名字"""
filename = 'username.json'
username = get_stored_username()
if username:
print("Welcome back, " + username + "!")
else:
username = get_new_username()
print("We'll remember you when you come back," + username)
greet_user()
11.1.1 单元测试和测试用例
11.1.2 可通过的测试
11.1.3 不能通过的测试
11.1.4 测试未通过时怎么办
11.1.5 添加新测试
使用Python模块 unittest 中的工具来测试代码.
要为函数编写测试用例,可先导入模块 unittest 以及要测试的函数,
再创建一个继承 unittest.TestCase 的类,并编写一系列方法对函数行为的不同方面进行测试。
name_function.py
def get_formatted_name(first, last, middle=''):
"""Generate a neatly formatted full name."""
if middle:
full_name = first + ' ' + middle + ' '+ last
else:
full_name = first + ' ' + last
return full_name.title()
test_name_ function.py
import unittest
from name_function import get_formatted_name
class NameTestCase(unittest.TestCase):
"""test name_function.py"""
def test_first_last_name(self):
formatted_name = get_formatted_name('janis', 'joplin')
self.assertEqual(formatted_name, 'Janis Joplin')
def test_first_last_middle_name(self):
formatted_name = get_formatted_name('wolfgang', 'mozart', 'amadeus')
self.assertEqual(formatted_name, 'Wolfgang Amadeus Mozart')
unittest.main()
11.2.1 各种断言方法
11.2.2 一个要测试的类
11.2.3 测试AnonymousSurvey类
11.2.4 方法setUp()
可在 setUp() 方法中创建一系列实例并设置它们的属性,再在测试方法中直接使用这些实例。相比于在每个测试方法中都创
建实例并设置其属性,这要容易得多。
survey.py
class AnonymousSurvey():
"""手机匿名调查问卷的答案"""
def __init__(self, question):
"""存储一个问题, 并未存储答案做准备"""
self.question = question
self.responses = []
def show_question(self):
"""显示调查问卷"""
print(self.question)
def store_response(self, new_response):
"""存储单份调查答卷"""
self.responses.append(new_response)
def show_results(self):
"""显示收集到的所有答卷"""
print("Survey results:")
for response in self.responses:
print('- ' + response)
test_survey.py
import unittest
from survey import AnonymousSurvey
class TestAnonmyousSurvey(unittest.TestCase):
"""test for class anonymousSurvey"""
#如果你在 TestCase 类中包含了方法 setUp() ,Python将先运行它,再运行各个以test_打头的方法。
def setUp(self):
"""
创建一个调查对象和一组答案,供使用的测试方法使用
"""
question = "What language did you first learn to speak?"
self.my_survey = AnonymousSurvey(question)
self.responses = ['English', 'Spanish', 'Mandarin']
def test_store_sinlge_response(self):
"""测试单个答案会被妥善地存储"""
question = "What language did you first learn to speak?"
self.my_survey.store_response(self.responses[0])
self.assertIn(self.responses[0], self.my_survey.responses)
def test_store_three_responses(self):
"""测试三个答案会被妥善地存储"""
for response in self.responses:
self.my_survey.store_response(response)
for response in self.responses:
self.assertIn(response, self.my_survey.responses)
unittest.main()