《python编程 从入门到实践》图林程序设计丛书 学习笔记
一,基础知识
(一)变量和简单数据类型
1,大小写
- 全大写:
name.lower()
- 全小写:
name.upper()
- 首字母大写:
name.title()
2,剔除空白格
- 剔除开头:
xx.lstrip()
- 剔除末尾:
xx.rstrip()
- 剔除两端:
xx.strip()
(二)列表&元祖
1,增删改元素
- 修改:liebiao[元素位置] = ’ 修改后的值 ’
- 添加:
1> 末尾添加:liebiao.append(' 元素 ')
2> 列表中插入:liebiao.insert (位置,'元素')
- 删除:
1>del liebiao[元素位置]
2>pop()
:删除(弹出)列表末尾元素 pop(元素位置):删除(弹出)任意位置元素
3>remove()
:根据值删除
2,组织列表(排序)
- 排序:
1>sort()
:永久性按字母顺序排序,若倒序那么只需向sort()
传参reverse=True
列表变量.sort()
2> sorted()
:临时性排序 sorted(参数1,参数2)
列表变量.sorte()
3>reverse()
:倒着打印列表 列表变量.reverse()
reversed(参数1,参数2)
4>len()
:确定列表长度
5> 列表索引从 0 开始,发生索引错误找不到解决方案,那么打印列表或其长度
3,操作列表(遍历-创建-解析)
遍历列表:
( for 循环注意缩进和 for 后面的冒号)
pizzas = ['fruit_pizza','cheese_pizza','beef_pizza']
for pizza in pizzas:
print(pizza)
创建数字列表:
1>range()
:生成一系列数字
创建数字列表
numbers = list(range(1:5))
指定步长2-11等差2
numbers = list(range(2:11:2))
数字列表统计计算
最大值:max()
;最小值:min()
;总值:sum()
列表解析(for循环给表达式提供值)
squares = [value**2 for value in range(1,11)]
4.使用列表的一部分
切片
列表名 [开始元素位置:结束元素位置+1]
遍历切片
for 循环遍历
复制列表
复制列表名 = 被复制列表名[:]
5,元祖
定义
不可变的列表称为元祖:元祖用 ( ) ,列表用 [ ] , 字典用 { }
遍历元祖所有值
for 循环遍历元祖,同列表
修改元祖变量
虽然不能修改元祖的值,但是可以给存储元祖的变量赋值,即重新定义整个元祖
6,设置代码格式
制表符代替空格键,行长80,遵循PER8指南
(三)if 语句
1,条件测试
大小写会影响值的判断;*!= 为不相等符号,== 为相等符号;*使用 and / or 来检查多个条件;检查特定值是否(不)包含在列表中;布尔表达式(True/False
)
2,if 语句
简单 if 语句
if conditional_text:
do something
if-else 语句
其中一个测试通过,那么就会跳过此此 if 语句余下的所有测试
if-elif-else
结构
可以使用多个 elif
代码块进行条件判断,也可省略 else 代码块
测试多个条件
多个条件多个if
语句
3,使用 if 语句处理列表
- 检查特殊元素
for
循环中包含if
语句 - 确定列表不是空的
list_1 = [***]
if list_1:
print('***')
else:
print('***')
- 使用多个列表
lists_1 = [***]
lists_2 = [***]
for list in lists_1:
if list1 in lists_2:
print('***')
else:
print('***')
( 四 )字典
1,使用字典
- 字典用放在
{ }
中的一系列任意数量的key-value
键值对表示。
direct = {key1:value1,key2:value2}
print(direct[key1])
----- 输出为:value1
- 添加键值对
direct = {} #创建新字典
direct[key2] = value2
direct[key3] = value3 #添加键值对
direct[key3] = value4 #修改字典中的值
del direct[key2] #删除键值对
- 由类似的对象组成字典
类似对象组成字典,可以多行存储,每个键值对以“,
”相隔,最后一个键值对也加上“,
”以便之后在下一行添加键值对。
2,遍历字典
在获取字典的元素时,获取顺序是不可预测的。
for key,value in direct.items(): #遍历所有键值对 方法items()
print('\nKey:' + key)
print('\nValue:' +value)
for key in direct.keys(): #遍历字典中所有的键 方法keys()
print(key)
for key in direct.values(): #遍历字典中所有的值 方法values()
print(value)
for key in sorted(direct.keys()): #按顺序遍历字典中的所有键,在for循环中对返回的键进行排序
print(key)
3,嵌套
- 将一系列字典存储在列表中,或将列表作为值存储在字典中
- 字典列表
direct_0 = {key_0:value_0,key_1:value_1}
direct_1 = {key_1:value_1,key_2:value_2}
direct_all = [direct_0,direct_1] #嵌套
for direct_number in range(30): #用 range 生成新的30个direct
new_direct = {new_key1 : new_value1,new_key2 : new_value2}
- 在字典中存储列表
direct_0 = {key_0:value_0,
key_1:[value_0,value_2]} #value为列表
- 在字典中存储字典
direct_all = {
direct_0 : {key_0:value_0,key_1:value_1} #字典名为key :字典内容为value
direct_1 : {key_1:value_1,key_2:value_2}
}
(五)用户输入和while循环
1,函数input()
的工作原理
- 函数
input()
让程序暂停,等待用户输入一些文本。获取用户输入后将其存储在一个变量中,方便使用。 - 提示可以存储在一个变量里面,再将该变量传递给函数
input()
tips = 'Welcome'
tips += 'what is your name ? '
name = input(tips)
print('\n name')
- 使用
int()
来获取数值输入(数据类型为 int 可以用作数据处理)
age = input('How old are you ?')
age = int(age)
if age >= 18:
print('You can play this game!')
- 求模运算(
%
)
两数相除返回余数 eg:4 % 3 == 1
2,while
循环简介
- 使用
while
循环
while number <= 10:
print('***')
number += 1
- 让用户选择何时退出
prompt = '1***'
prompt += '11***'
message = '111**'
whlie message != 'quit':
message = input(promt)
if message != 'quit'
print(message)
active = True #使用标志 active
while active:
if message == 'quit'
active = False
else
print(message)
- 使用
break
退出循环
以while True
打头的循环将不断进行,直到遇到break
语句。
message = ''
while message != 'quit':
message = input('what kind of peiliao you want?')
print('we will add this peiliao for you : ' + message)
if message == 'quit':
break
- 在循环中使用
continue
返回循环开头,并根据条件测试结果决定是否继续执行循环。 - 避免无限循环
3,while 循环处理列表和字典
- 在列表之间移动元素
whlie 循环将需要移动的列表元素从末尾删除的同时存储到一个变量,再将该变量添加到需要移动到的列表里。
sandwich_order = ['apple','banna','ice_cream']
finished_order = []
while sandwich_order:
middle = sandwich_order.pop()
print('I made you tuna sandwich :' + middle)
finished_order.append(middle)
print(finished_order)
- 删除包含特定值的所有列表元素
whlie
循环remove()
函数删除知道别表中无该元素
sandwich_order = ['apple','banna','ice_cream','pastrami','pastrami','pastrami']
print('五香烟熏牛肉卖完啦!')
while 'pastrami' in sandwich_order:
sandwich_order.remove('pastrami')
print(sandwich_order)
- 使用用户输入来填充字典
while
循环提示用户输入任意量的信息,再将收集的数据存储在一个字典里
reponses = {}
active = True
while active: #使用标志
name = input('What is your name? ')
color = input('what color you like? ')
reponses[name] = color #将收集的数据存储在字典里
for name,color in reponse.items():
print(name + 'favorite color is : ' + color)
(六)函数
1,定义函数
- 实参:实际传入的值参数 形参:函数定义的参数
2,传递实参
- 位置实参(基于实参的顺序)
1> 调用函数多次
2> 位置实参的顺序很重要 - 关键字实参
1> 传递给函数的是 名称-值 对 - 默认值
1> 在定义函数时可以给每个参数指定默认值,在调用函数时给形参提供了实参时,将使用指定的实参,否则使用默认值。
2> 使用默认值时,在参数列表中必须先列出没有默认值的形参,再列出有默认值的形参。 - 等效的函数调用
1> 鉴于可混合使用位置参数,关键值参数和默认值,通常有多种等效的函数调用。
3,返回值
- 返回简单值
1> 在函数中,可使用return
语句将值返回到调用函数的代码行。
2> 调用返回值函数时,需要提供一个变量用于存储返回的值。 - 让实参变成可选的
1> 可以使用默认值设置为空字符串来让实参变成可选的。
2> 用 if 语句来判断是否传入可变实参,分情况返回值。 - 返回字典
def make_album(musican,album_name,song_numbers = ''):
album = {'musican': musican, 'album_name': album_name}
if song_numbers:
album['song_numbers'] = song_numbers
else:
return album
return album
My_album = make_album('max','maxin',5)
print(My_album)
My_album = make_album('mat','matao')
print(My_album)
- 结合使用函数和
whlie
循环 (注意定义退出条件)
def make_album(musican,album_name,song_numbers = ''):
album = {'musican': musican, 'album_name': album_name}
return album
while True:
f_musican = input('输入你喜欢的音乐家')
if f_musican == 'q':
break
f_album = input('输入他/她的专辑名称')
if f_album == 'q':
break
My_album = make_album(f_musican,f_album)
print(My_album)
4,传递列表
- 在函数中修改列表
def show_magicicans(names):
for name in names:
print(name)
def make_great(names):
for idx, name in enumerate(names): #函数 enumerate() 遍历返回元素位置以及元素内容!
name_new = 'the Great ' + name
names[idx] = name_new
print(name_new)
print(names)
list_magicican = ['a','b','c','d'] #先把实参传入变量再带入函数这样函数传入的是同一变量!
show_magicicans(list_magicican)
make_great(list_magicican)
show_magicicans(list_magicican)
- 禁止函数修改列表
切片表示法[:]
创建列表副本。
5,传递任意数量的实参
*
号让 Python 创建一个空元祖,将收到的所有实参都封装到这个元祖里。- 结合使用位置实参和任意数量实参
1> 如果要让函数接受不同类型的实参,必须在函数定义中将接纳任意数量实参的形参放在最后。 - 使用任意数量的关键字实参
1>**
双星号让 Python 创建一个空字典,并将收到的所有 名称-值 对封装到这个字典里。
6,将函数存储在模块中
- 模块
1>import
语句允许在当前运行的程序中使用模块中的代码。
2> 模块是扩展名为 .py 的文件,包含要导入到程序中的代码。 - 导入整个模块
import pizza #导入模块
pizza.make_pizza('a') #调用模块函数
- 导入特定函数
from pizza import make_pizza,do_pizza #from 模块 import 函数1,函数2
make_pizza(12,'a')
do_pizza(23,'b')
- 使用
as
给 函数 / 模块 指定别名 & 导入模块中的所有函数
import pizza as mat #给模块起别名
from pizza import make_pizza as mot #避免函数名重复,给 make_pizza 取别名 mot
from pizza import * #导入模块中的所有函数
mot(12,'a')
(七)类
- 首字母大写的名称指的是类
- 类中的函数称为: 方法
1,创建和实用类
- 创建 Dog 类
1> 方法__init__()
每个与类相关联的方法调用都会自动传递实参self
,它是一个指向实例本身的引用,让实例能够访问类中的属性和方法。
以 self 为前缀的变量都可供类中的所有方法使用,还可以通过类的任何实例来访问这些变量。
2> 根据类创建实例
· 访问属性: 可使用句点表示法 eg:my_dog.name
: 先找到实例 my_dog ,在找到相关联属性 name 。
· 调用方法: 可指定实例的名称和要调用的方法,并用句号分割他们。
· 创建多个实例: 可根据一个类创建任意数量实例,条件是将每个实例都存储在不同的变量中,或占用列表或字典的不同位置。
class Restaurant(): #创建类
def __init__(self,restaurant_name,cuisine_type): #__init__初始化对象
self.restaurant_name = restaurant_name #将形参存储在实例属性中
self.cuisine_type = cuisine_type
def describe_restaurant(self): #定义对象的方法
print('Restaurant message is : ' + self.restaurant_name + self.cuisine_type)
def open_restaurant(self):
print('Restaurant is opening !')
my_restaurant = Restaurant('matao','maxin') #创建对象/实例化
my_restaurant.describe_restaurant() #调用对象方法
my_restaurant.open_restaurant() #调用对象方法
2,使用类和实例
- 给属性指定默认值
- 修改属性的值
1> 直接修改属性值
2> 通过方法修改属性值
3> 通过方法对属性的值进行递增
class Car:
def __init__(self,make,model,year):
self.make = make
self.model = model
self.year = year
self.mile = 0 #设置初始值
def read_mile(self):
print('汽车里程为:' + str(self.mile) + ' miles')
def update_mile(self,new_mile): #通过方法修改属性值 1
self.mile = new_mile
self.mile += new_mile #通过方法对属性的值进行递增
my_new_car = Car('a','b','c')
# my_new_car.mile = 6 #直接修改属性值
my_new_car.update_mile(23) #通过方法修改属性值 2
my_new_car.read_mile()
3,继承
- 子类的方法
__init__
1>super()
函数将父类和子类关联起来。
class Restaurant(): #父类
def __init__(self,restaurant_name,cuisine_type):
self.restaurant_name = restaurant_name
self.cuisine_type = cuisine_type
def describe_restaurant(self):
print('Restaurant message is : ' + self.restaurant_name + self.cuisine_type)
def open_restaurant(self):
print('Restaurant is opening !')
class IceCreamStand(Restaurant): #子类
def __init__(self, restaurant_name, cuisine_type, flavors=None):
super().__init__(restaurant_name, cuisine_type)
self.flavors = flavors
def ice_taste(self):
for flavor in flavors:
print('The taste is : ' + flavor)
flavors = ['apple','banana']
ice_cream = IceCreamStand('matao','new_type')
ice_cream.describe_restaurant()
ice_cream.ice_taste()
- 给子类定义属性和方法
class A(B): #子类
def __init__(self,a,b,c): #__init__初始化父类的属性(复制父类的 __init__() )
super.__init__(a,b,c)
self.c = c #添加子类新属性
def hu(self): #重写父类的方法 1
print('***') #重写父类的方法 2
- 将实例用作属性
1> 可以将大型类拆分成多个小类,大类调用小类作为属性。
class Admin(User):
def __init__(self, first_name, last_name, gander, age):
super().__init__(first_name, last_name, gander, age)
self.privileges = Privileges() #将实例用作属性
class Privileges(): #创建类
def __init__(self, privileges=None):
self.privileges = privileges
def show_privileges(self):
for privilege in privileges:
print(privilege)
privileges = ['can do post','can delete post','can be user']
ndijn = Admin('Ma','Xin','nv','24',)
ndijn.privileges.show_privileges()
4,导入类
- 将类存储在模块里,使用的时候再
import()
导入模块以保证主程序整洁易阅读。 - 可根据需要在一个模块中存储任意数量的类。
- 也可以从一个模块导入多个类:
from aa import bb, cc
- 导入整个模块:
import gg
- 导入模块中的所有类:
from hh import *
(不推荐) - 在一个模块中导入另一个模块:
from a1 import b
(八)文件和异常
1,从文件中读取数据
- 读取整个文件
1> 函数 open() 接受一个参数:要打开的文件的名称with open(文件名) as ***
with open(文件名) as file_object:
contents = file_object.read()
pi_string = ''
for line in contents: # 逐行读取 1
pi_string += line.strip() #逐行相加删去前后空白符
print(line) # 逐行读取 2
print(pi_string) #使用文件的内容
print(contents) # 读取整个文件
- 文件路径
1> 可以使用相对文件路径或者绝对文件路径(路径较长可以先存着变量里再将变量传递给open()
)来读取文件。 - 逐行读取:
for循环
- 创建一个包含文件合行内容的列表
1>readlines()
从文件中读取每一行,并将其存储在一个列表里。 - 使用文件的内容
1> 读取文件时都解读为字符串,数字必须用int()
或者float()
将其转化为正数或者浮点数。 - 包含一百万位的大型文件:只要内存足够,没有任何限制
- 圆周率中包含你的生日吗 :
if
判断语句
2,写入文件
- 写入空文件
1> 读取模式(’ r ‘),写入模式(’ w ‘),附加模式(’ a ')
2> 要将文本写入文件要给 open() 再传入一个实参’ w '。
with open(filename,'w') as ***:
***.write('***')
3> 以写入模式打开已存在的文件时,返回文件对象前会清空文件。文件不存在的会自动创建新文件。
- 写入多行
1> 要让字符串独占一行,需要在write()
语句里包含换行符。 - 附加到文件
1> 添加内容而不是覆盖内容要使用附加模式,要给 open() 再传入一个实参’ a '。
3,异常
- 处理
ZeroDivisionError
异常:不能将一个数字除以0 - 使用
try-except
代码块 - 使用异常避免奔溃
-
else
代码块 - 处理
FileNotFoundError
异常 - 分析文本:
split()
函数以分隔符将字符串拆分成多个部分,并将这些部分都存储到一个列表中。 - 使用多个文件
- 失败时一声不吭:
try-except
时报错无操作直接 pass - 决定报告哪些错误
4,存储数据
- 使用
json.dump()
和json.load()
1>json.dump()
:存储一组数字
· 导入模块:improt json
· 接受两个实参:要存储的数据和可用于存储数据的文件对象。
· 通常使用.jason
来指出文件存储格式为:JSON
· 以写入模式打开文件以保证json
能将数据写入其中
2>json.load()
:将这些数字读取到内存 - 保存和读取用户生成的数据
import json
file_name = 'remember_message'
try:
with open(file_name) as xxx_name:
user_name = json.load(xxx_name) #读取用户生成的数据
print('Welcom bake ' + user_name)
except FileNotFoundError:
user_name = input('What`s your name ?')
print('Welcom ' + user_name)
with open(file_name,'w') as file1_name: #保存用户生成的数据
json.dump(user_name,file1_name)
print('We will remember you :' + user_name )
- 重构
定义:将代码划分成一系列完成具体工作的函数。需要在添加新代码前重构既有代码,旨在简化现有代码的结构,使其更容易扩展。
(九)测试代码
使用 Python 模块 unittest
中的工具来测试代码。
1,测试函数
- 单元测试和测试用例
1> 单元测试:核实函数的某个方面没有问题
2> 测试用例:一组单元测试,考虑到函数可能收到的各种输入
3> 全覆盖测试:一整套单元测试,涵盖了各种可能的函数使用方式 - 可通过的测试
1> 编写测试用例:
a,导入模块unittest
以及要测试的函数
b,创建一个继承unittest.TestCase
的类,类命名包含‘Test’
字样
c,编写一系列方法对函数行为的不同方面进行测试,方法名必须‘Test’
打头,这样他才会自动运行
2>unittest
的 断言方法assertEqual(测试返回值,'测试期望值')
将测试返回值和测试期望值作比较是否一致。 - 不能通过的测试
- 测试未通过时怎么办
1> 检查修改的代码是否可以运行测试输入 - 添加新测试
1> 根据不同条件编写新测试,测试方法名可以是很长的,且必须是描述性的,这样才能明白测试未通过时的输出。
· city_functions.py
def city_country(city,country):
city_country_1 = city.title()+ ',' + country.title()
return city_country_1
· test.cities.py
import unittest
from city_functions import city_country
class City_Country(unittest.TestCase):
def test_city_country(self):
city_country_test = city_country('santiago','chile')
self.assertEqual(city_country_test ,'Santiago,Chile')
unittest.main()
2,测试类
- 各种断言方法(只能在继承
unittest.TestCase
的类中使用这些方法)
assertEqual(a,b) # 核实a==b
assertNotEqual(a,b) # 核实a!=b
assertTrue(x) # 核实 x 为 True
assertFalse(x) # 核实 x 为 False
assertIn(item,list) # 核实 item 在 list 中
assertNotIn(item,list) # 核实 item 不在 list 中
- 一个要测试的类
- 测试
AnonymousSurvey()
类 - 方法
setUp()
在TestCase
类中包含方法setUp()
,Python将先运行setUp()
再运行以test_
打头的方法
raise_employee
class Employss:
def __init__(self,first_name,last_name,annual_salary):
self.first_name = first_name
self.last_name = last_name
self.annual_salary = annual_salary
def give_raise(self,raise_salary = 5000):
self.raise_salary = raise_salary
self.annual_salary += self.raise_salary
print(self.annual_salary)
return self.annual_salary
test_raise_employee
import unittest
from raise_employee import Employss
class Test_give_raise(unittest.TestCase):
def setUp(self):
self.my_employee = Employss('ma', 'xin', 6000)
def test_give_default_raise(self): #测试给予默认提升
give_default_raise_test = self.my_employee.give_raise()
self.assertEqual(give_default_raise_test,11000)
def test_give_custom_raise(self): #测试给予定制提升
give_custom_raise_test = self.my_employee.give_raise(3000)
self.assertEqual(give_custom_raise_test, 9000)
unittest.main()