第八章 导入模块
pizza.py
def make_pizza(size, *toppings):
"""概述要制作的比萨"""
print("\nMaking a " + str(size) + "-inch pizza with the following toppings:")
for topping in toppings:
print("- " + topping)
test.py
import pizza
pizza.make_pizza(16, 'pepperoni')
pizza.make_pizza(12, 'mushrooms', 'green peppers', 'extra cheese')
导入特定的函数
语法:from module_name import function_name
from module_name import function_0, function_1, function_2
pizza.py
def make_pizza(size, *toppings):
"""概述要制作的比萨"""
print("\nMaking a " + str(size) + "-inch pizza with the following toppings:")
for topping in toppings:
print("- " + topping)
test.py
from pizza import make_pizza
make_pizza(16, 'pepperoni')
make_pizza(12, 'mushrooms', 'green peppers', 'extra cheese')
使用使 as 给函数指定别名 typedef
如果要导入的函数的名称可能与程序中现有的名称冲突,或者函数的名称太长,可指定简短而独一无二的别名别 ——函数的另一个名称
下面给函数make_pizza() 指定了别名mp() 。这是在import 语句中使用make_pizza as mp 实现的,关键字as 将函数重命名为你提供的别名:
pizza.py
def make_pizza(size, *toppings):
"""概述要制作的比萨"""
print("\nMaking a " + str(size) + "-inch pizza with the following toppings:")
for topping in toppings:
print("- " + topping)
test.py
from pizza import make_pizza as mp
mp(16, 'pepperoni')
mp(12, 'mushrooms', 'green peppers', 'extra cheese')
使用使 as 给模块指定别名
import pizza as p
p.make_pizza(16, 'pepperoni')
p.make_pizza(12, 'mushrooms', 'green peppers', 'extra cheese')
导入模块中的所有函数 (*)
from pizza import *
make_pizza(16, 'pepperoni')
make_pizza(12, 'mushrooms', 'green peppers', 'extra cheese')
第九章 类
- 使用类几乎可以模拟任何东西。
- 下面来编写一个表示小狗的简单类Dog ——它表示的不是特定的小狗,而是任何小狗
- 它们都有名字 和年龄
- 我们还知道,大多数小狗还会蹲下和打滚
- 这个类让 Python知道如何创建表示小狗的对象。编写这个类后,我们将使用它来创建表示特定小狗的实例。
方法方 init() 初始化类
开头和末尾各有两个下划线 这是一种约定,旨在避免Python默认方法与普通方法发生名称冲突。
我们将方法__init__() 定义成了包含三个形参:self 、name 和age 。
形参self 必不可少,还必须位于其他形参的前面。为何必须在方法定义中包 含形参self 呢?因为Python调用这个__init__() 方法来创建Dog 实例时,将自动传入实参self 。 它是一个指向实例本身 的引用,让实例能够访问类中的属性和方法
class Dog():
"""一次模拟小狗的简单尝试"""
def __init__(self, name, age):
"""初始化属性name和age"""
self.name = name
self.age = age
def sit(self):
"""模拟小狗被命令时蹲下"""
print(self.name.title() + " is now sitting.")
def roll_over(self):
"""模拟小狗被命令时打滚"""
print(self.name.title() + " rolled over!")
my_dog = Dog('willie', 6)
print("My dog's name is " + my_dog.name.title() + ".")
print("My dog is " + str(my_dog.age) + " years old.")
访问类的变量和函数 .
class Dog():
"""一次模拟小狗的简单尝试"""
def __init__(self, name, age):
"""初始化属性name和age"""
self.name = name
self.age = age
def sit(self):
"""模拟小狗被命令时蹲下"""
print(self.name.title() + " is now sitting.")
def roll_over(self):
"""模拟小狗被命令时打滚"""
print(self.name.title() + " rolled over!")
my_dog = Dog('willie', 6)
my_dog.sit()
my_dog.roll_over()
使用类创建多个实例
class Dog():
"""一次模拟小狗的简单尝试"""
def __init__(self, name, age):
"""初始化属性name和age"""
self.name = name
self.age = age
def sit(self):
"""模拟小狗被命令时蹲下"""
print(self.name.title() + " is now sitting.")
def roll_over(self):
"""模拟小狗被命令时打滚"""
print(self.name.title() + " rolled over!")
my_dog = Dog('willie', 6)
your_dog = Dog('lucy', 3)
print("My dog's name is " + my_dog.name.title() + ".")
print("My dog is " + str(my_dog.age) + " years old.")
my_dog.sit()
print("\nYour dog's name is " + your_dog.name.title() + ".")
print("Your dog is " + str(your_dog.age) + " years old.")
your_dog.sit()
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 = str(self.year) + ' ' + self.make + ' ' + self.model
return long_name.title()
my_new_car = Car('audi', 'a4', 2016)
print(my_new_car.get_descriptive_name())
给类属性(变量)----指定默认值
下面来添加一个名为odometer_reading 的属性,其初始值总是为0。我们还添加了一个名为read_odometer() 的方法,用于读取汽车的里程表:
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.")
my_new_car = Car('audi', 'a4', 2016)
print(my_new_car.get_descriptive_name())
my_new_car.read_odometer()
修改类属性的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
def increment_odometer(self, miles):
"""将里程表读数增加指定的量"""
self.odometer_reading += miles
my_new_car = Car('audi', 'a4', 2016)
print(my_new_car.get_descriptive_name())
"""直接修改"""
my_new_car.odometer_reading = 23
"""方法修改"""
my_new_car.update_odometer(23)
"""新增修改"""
my_new_car.increment_odometer(23)
my_new_car.read_odometer()
继承!!!super()
super() 是一个特殊函数,帮助Python将父类和子类关联起来
一个类继承继 另一个类时,**它将自动获得另一个类的所有属性和方法;**原有的 类称为父类父 ,而新类称为子类子 。子类继承了其父类的所有属性和方法,同时还可以定义自己的属性和方法。
定义子类时,必须在括号内指定父类的
例如:class ElectricCar(Car): Car 这个就是名称
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
def increment_odometer(self, miles):
"""将里程表读数增加指定的量"""
self.odometer_reading += miles
class ElectricCar(Car):
def __init__(self, make, model, year):
super().__init__(make, model, year)
my_tesla = ElectricCar('tesla', 'model s', 2016)
print(my_tesla.get_descriptive_name())
给子类定义属性和方法
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
def increment_odometer(self, miles):
"""将里程表读数增加指定的量"""
self.odometer_reading += miles
class ElectricCar(Car):
def __init__(self, make, model, year):
""" 电动汽车的独特之处 初始化父类的属性,再初始化电动汽车特有的属性 """
super().__init__(make, model, year)
self.battery_size = 70
def describe_battery(self):
"""打印一条描述电瓶容量的消息"""
print("This car has a " + str(self.battery_size) + "-kWh battery.")
my_tesla = ElectricCar('tesla', 'model s', 2016)
print(my_tesla.get_descriptive_name())
my_tesla.describe_battery()
重写父类的方法
对于父类的方法,只要它不符合子类模拟的实物的行为,都可对其进行重写
即它与要重写的父类方法同名。这样,Python将不会考虑这 个父类方法,而只关注你在子类中定义的相应方法。
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
def increment_odometer(self, miles):
"""将里程表读数增加指定的量"""
self.odometer_reading += miles
def fill_gas_tank(self):
"""汽车有油箱"""
print("This car need a gas tank!")
class ElectricCar(Car):
def __init__(self, make, model, year):
""" 电动汽车的独特之处 初始化父类的属性,再初始化电动汽车特有的属性 """
super().__init__(make, model, year)
self.battery_size = 70
def describe_battery(self):
"""打印一条描述电瓶容量的消息"""
print("This car has a " + str(self.battery_size) + "-kWh battery.")
def fill_gas_tank(self):
"""电动汽车没有油箱"""
print("This car donot need a gas tank!")
my_tesla = ElectricCar('tesla', 'model s', 2016)
print(my_tesla.get_descriptive_name())
my_tesla.describe_battery()
my_tesla.fill_gas_tank()
将类的一部分提取出来成一个小类
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
def increment_odometer(self, miles):
"""将里程表读数增加指定的量"""
self.odometer_reading += miles
def fill_gas_tank(self):
"""汽车有油箱"""
print("This car need a gas tank!")
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 = Battery()
my_tesla = ElectricCar('tesla', 'model s', 2016)
print(my_tesla.get_descriptive_name())
my_tesla.battery.describe_battery()
将一个特定的类使用模块
下面来创建一个只包含Car 类的模块。这让我们面临一个微妙的命名问题:在本章中,已经有一个名为car.py的文件,但这个模块也应命名为car.py,因为它包含表示汽车的代 码。我们将这样解决这个命名问题:将Car 类存储在一个名为car.py的模块中,该模块将覆盖前面使用的文件car.py。从现在开始,使用该模块的程序都必须使用更具体的文件 名,如my_car.py。下面是模块car.py,其中只包含Car 类的代码:
在这里插入代码片
导入单个类
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 = 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
def increment_odometer(self, miles):
"""将里程表读数增加指定的量"""
self.odometer_reading += miles
def fill_gas_tank(self):
"""汽车有油箱"""
print("This car need a gas tank!")
test.py
from car import Car
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 = Battery()
my_tesla = ElectricCar('tesla', 'model s', 2016)
print(my_tesla.get_descriptive_name())
my_tesla.battery.describe_battery()
在一个文件中存储多个类
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 = 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
def increment_odometer(self, miles):
"""将里程表读数增加指定的量"""
self.odometer_reading += miles
def fill_gas_tank(self):
"""汽车有油箱"""
print("This car need a gas tank!")
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 = Battery()
test.py
from car import ElectricCar
my_tesla = ElectricCar('tesla', 'model s', 2016)
print(my_tesla.get_descriptive_name())
my_tesla.battery.describe_battery()
一个模块中导入多个类&&导入整个模块&&导入模块中的所有类
from car import Car, ElectricCar
import car
from module_name import *
在一个模块中导入另一个模块
- 有时候,需要将类分散到多个模块中,以免模块太大,
- 在同一个模块中存储不相关的类。将类存储在多个模块中时,
- 你可能会发现一个模块中的类依赖于另一个模块中的类。 在这种情况下,可在前一个模块中导入必要的类。
在这里插入代码片
Python标准库!!!
你现在对类的工作原理已有大致的了解,可以开始使用其他程序员编写好的模块了
来看模块collections 中的一个类——OrderedDict 。
OrderedDict 实例的行为几乎与字典相同,区别只在于记录了键—值对的添加顺序。
from collections import OrderedDict
favorite_languages = OrderedDict()
favorite_languages['jen'] = 'python'
favorite_languages['sarah'] = 'c'
favorite_languages['edward'] = 'ruby'
favorite_languages['phil'] = 'python'
for name, language in favorite_languages.items():
print(name.title() + "'s favorite language is " + language.title() + ".")
第十章 :文件和异常
文本文件可存储的数据量多得难以置信:
- 天气数据、
- 交通数据、
- 社会经济数据、
- 文学作品等。
每当需要分析或修改存储在文件中的信息时,读取文件都很有用,对数据分析应用 程序来说尤其如此。例如,你可以编写一个这样的程序:读取一个文本文件的内容,重新设置这些数据的格式并将其写入文件,让浏览器能够显示这些内容。 要使用文本文件中的信息,首先需要将信息读取到内存中。为此,你可以一次性读取文件的全部内容,也可以以每次一行的方式逐步读取。
打开文件函数open()
注意如下:
-
函数open() 接受一个参数:要打开的文件的名称。
-
函数open() 返回一个表示文件的对象
-
在这里,open(‘data.txt’) 返回一个表示文件pi_digits.txt 的对象;Python将这个对象存储在我们将 在后面使用的变量中。
-
关键字with 在不再需要访问文件后将其关闭。
在这个程序中,注意到我们调用了open() ,但没有调用close() ; -
你也可以调用open() 和close() 来打开和关闭文件,但 这样做时,如果程序存在bug,导致close() 语句未执行,文件将不会关闭。
建议可以使用with 让python 自动关闭文件。
with open('data.txt') as file_object:
contents = file_object.read()
print(contents)
Python方法rstrip() 删除(剥除)字符串末尾的空白
文件路径
要让Python打开不与程序文件位于同一个目录中的文件,需要提供文件路径 ,它让Python到系统的特定位置 去查找。
with open('python/data.txt') as file_object:
contents = file_object.read()
print(contents)
在Windows系统中,在文件路径中使用反斜杠(\ )而不是斜杠(/ ):
with open('python\data.txt') as file_object:
contents = file_object.read()
print(contents)
with open('python/data.txt') as file_object:
contents = file_object.read()
print(contents)
绝对路径
path = 'D:\360MoveData\Users\13182\Desktop\data.txt'
with open(path) as file_object:
contents = file_object.read()
print(contents)
创建一个包含文件各行内容的列表readlines()
使用关键字with 时,open() 返回的文件对象只在with 代码块内可用。
如果要在with 代码块外访问文件的内容,可在with 代码块内将文件的各行存储在一个列表中,并 在with 代码块外使用该列表:
你可以立即处理文件的各个部分,也可推迟到程序后面再处理。
filename = 'flash_GD-TYWE3S_1.log'
filename1 = 'data.txt'
with open(filename1) as file_object:
lines = file_object.readlines()
pi_string = ''
for line in lines:
pi_string += line.strip()
print(pi_string)
print(len(pi_string))
写入文件
在这个示例中,调用open() 时提供了两个实参(见❶)。
- 第一个实参也是要打开的文件的名称;
- 第二个实参(‘w’ )告诉Python,
- 如果你要写入的文件不存在,函数open() 将自动创建它
- 以写入(‘w’ )模式打开文件时千万要小心,因为如果指定的文件已经存在,Python将在返回文件对象前清空 该文件。
filename = 'data.txt'
with open(filename, 'w') as file_object:
file_object.write("I love programming.")
写入多行 \n
filename = 'data.txt'
with open(filename, 'w') as file_object:
file_object.write("I love programming.\n")
file_object.write("I love programming.\n")
异常使用使 try-except 代码块
try:
print(5/0)
except ZeroDivisionError:
print("You can't divide by zero!")
附加到文件 ‘a’
如果你要给文件添加内容,而不是覆盖原有的内容,可以附加模式 附 打开文件。
filename = 'data.txt'
with open(filename, 'a') as file_object:
file_object.write("I love programming.\n")
file_object.write("I love programming.\n")
存储数据 json格式,json.dump() 和json.load()
import json
numbers = [2, 3, 5, 7, 11, 13]
filename = 'numbers.json'
with open(filename, 'w') as f_obj:
json.dump(numbers, f_obj)
import json
filename = 'numbers.json'
with open(filename) as f_obj:
str = f_obj.read()
num = json.loads(str)
print(num)
保存和读取用户生成的数据
import json
filename = 'numbers.json'
username = input("What is your name? ")
with open(filename,'w') as f_obj:
json.dump(username, f_obj)
print("We'll remember you when you come back, " + username + "!")
第 11 章 测试代码
测试函数-unittest 类
Python标准库中的模块unittest 提供了代码测试工具
。良好的测试用例考虑到了函数可能收到的各种输入,包含针对所有这些情形的测试。全覆盖式测试 全 用例包含一整套单元测试
import unittest
from my_class import get_formatted_name
class NamesTestCase(unittest.TestCase):
"""测试name_function.py"""
def test_first_last_name(self):
"""能够正确地处理像Janis Joplin这样的姓名吗?"""
formatted_name = get_formatted_name('janis', 'joplin')
self.assertEqual(formatted_name, 'Janis Joplin')
unittest.main()
因此我们期望formatted_name 的值为Janis Joplin 。为检查是否确实如此,我们调用unittest 的方法assertEqual() ,并向它传递formatted_name 和’Janis Joplin’ 。代码行self.assertEqual(formatted_name, ‘Janis Joplin’) 的意思是 说:“将formatted_name 的值同字符串’Janis Joplin’ 进行比较,如果它们相等,就万事大吉,如果它们不相等,跟我说一声!”
不能通过的测试
my_class.py
def get_formatted_name(first, middle, last):
"""Generate a neatly formatted full name."""
full_name = first + ' ' + middle + ' ' + last
return full_name.title()
test.py
import unittest
from my_class import get_formatted_name
class NamesTestCase(unittest.TestCase):
"""测试name_function.py"""
def test_first_last_name(self):
"""能够正确地处理像Janis Joplin这样的姓名吗?"""
formatted_name = get_formatted_name('janis', 'joplin')
self.assertEqual(formatted_name, 'Janis Joplin')
unittest.main()
我们看到了一个标准 的traceback,它指出函数调用get_formatted_name(‘janis’, ‘joplin’) 有问题,因为它缺少一个必不可少的位置实参。
添加新测试
import unittest
from my_class import get_formatted_name
class NamesTestCase(unittest.TestCase):
"""测试name_function.py"""
def test_first_last_name(self):
"""能够正确地处理像Janis Joplin这样的姓名吗?"""
formatted_name = get_formatted_name('janis', 'joplin')
self.assertEqual(formatted_name, 'Janis Joplin')
def test_first_last_middle_name(self):
"""能够正确地处理像Wolfgang Amadeus Mozart这样的姓名吗?"""
formatted_name = get_formatted_name( 'wolfgang', 'mozart', 'amadeus')
self.assertEqual(formatted_name, 'Wolfgang Amadeus Mozart')
unittest.main()
unittest Module中的断言方法
背景
在这里插入代码片
```## 背景
```javascript
在这里插入代码片
背景
在这里插入代码片
背景
在这里插入代码片
背景
在这里插入代码片