《Python编程 从入门到实践》Eric Matthes 简单读书笔记
第2章 变量和简单数据类型
python中的分号可以省略,主要通过换行来识别语句的结束,但是如果在一行中书写多条语句,就必须使用分号分隔每条语句。
2.3 字符串
在python中,用引号括起来的都是字符串,其中的引号可以是单引号也可以是双引号。
方法title()将每个单词的首字母都改为大写。 upper()将字符串改为全部大写, lower()将字符串改为全部小写。但是这三个函数不会改变存储在变量中的值,只是临时改变。
python使用加号(+)来合并字符串。
要在字符串中添加制表符,可使用字符组合 ,(记忆方法table),要在字符串中添加换行符,可使用字符组合 。例如
print(“Language: python C java”)打印结果如下
Language
python
C
java
strip剔除字符串两端的空白,lstrip剔除字符串开头的空白,rstrip剔除字符串末尾多余的空白,记忆方法:strip脱去衣服,修剪树枝, l:left, r:right.
favourite_language.strip()
2.4数字
python使用两个**表示乘方运算,3**2=9 3**4=81
python将带小数点的数字都称为浮点数。
在字符串中使用整数时,需要用str函数显式地将这个整数用作字符串,例如
age = 23
message = "happy" + str(age) + "rd birrhday"
print(message)
如果没有str函数,程序将运行失败。
python中注释用井号(#)标识。
第3章 列表简介
列表由一系列按特定顺序排列的元素组成,在python中,用方括号([ ])来表示列表,并用逗号来分隔其中的元素。
第一个列表元素的索引为0,
python为访问最后一个列表元素提供了一种特殊语法,通过将索引指定为-1,可以让python返回最后一个列表元素,索引-2返回倒数第二个列表元素,索引-3返回倒数第三个列表元素,以此类推。
修改列表元素就是直接对该元素重新赋值就好了,
方法append()将元素添加到列表末尾。例如 motorcycles.append(‘ducati’)
方法insert()可在列表的任何位置添加新元素,添加时需要制定新元素的索引和值,例如,motorcycles.insert(0, 'ducati'),操作之后,列表中既有的每个元素都右移一个位置。
1.使用delete语句删除元素,del motorcycles[0] 删除索引为0的元素
2.使用方法pop删除元素,方法pop()可删除列表末尾的元素,并让你能够接着使用它, 列表就像一个栈,pop就相当于弹出栈顶元素。popped_motorcycles = motorcycles.pop() 此操作之后,列表末尾元素被删除并且赋值给了变量popped_motorcycles
3.弹出列表中任何位置处的元素,你可以使用pop()来删除列表中任何位置的元素,只需要在括号中指定要删除的元素的索引即可。
4.根据值删除元素,有时候你不知道要从列表中删除的值所处的位置,可以用remove根据值删除元素,例如,motorcycles.remove('ducati') 方法remove只删除第一个指定的值,如果要删除的值可能在列表中出现多次,就需要使用循环来判断是否删除了所有这样的值。
3.3组织列表
3.3.1使用方法sort()对列表按照字母顺序进行永久性排序, 排序后再也无法恢复到原来的排列顺序。 通过向方法sort()传递参数reverse=True是列表按照首字母顺序相反的顺序排列列表,例如cars.sort(reverse=True)
3.3.2使用函数sorted对列表进行临时排序,例如print(sorted(cars)) 只是临时的,原始顺序并没有变,注意sorted不是列表的成员函数,而sort和reverse都是列表的成员函数,
3.3.3 反转,要反转列元素的排列顺序,可使用方法reverse() cars.reverse()
3.3.4 使用函数len()可快速获悉列表的长度。 len(cars)
3.4使用列表时避免索引错误
第4章 操作列表
4.1遍历整个列表
for循环,
magicians = ['alice', 'david', 'carolina']
for magician in magicians:
print(magician)
for循环后面每个缩进的代码行都是循环的一部分,因此想在一个for循环中包含多条语句时,只需要把多行语句都缩进即可。另外,注意for语句后面有冒号。
4.3创建数字列表
for value in range(1,5):
print(value)
注意此示例中,只会打印1 2 3 4,不会打印5,
可以使用函数list()将range()的结果直接转换为列表,例如
numbers = list(range(1,6))
print(numbers)
打印结果为:[1, 2, 3, 4, 5]
4.3.3对数字列表执行简单的统计运算
有几个专门用于处理数字列表的python函数,可以求最大值,最小值,和,例如
digits = [1, 2, 3, 4, 5, 6]
min(digits)
max(digits)
sum(digits)
4.3.4列表解析
squares = [value**2 for value in range(1, 11)]
print(squares)
4.4使用列表的一部分
列表的部分元素成为切片
player = ['x', 'y', 'z', 'm', 'n']
print(player[0:3])
打印结果为['x', 'y', 'z']
player([a:b])是指从a到b-1的元素,
player([:b])是指从开始到b-1的元素
player([a:])是指从a到列表结束的元素
还可以在for循环中使用切片
for play in player[:3]
4.4.3 复制列表
要复制列表,可创建一个包含整个列表的切片,方法是同时省略起始索引和终止索引([:])
my_foods = ['pizza', 'falafel', 'carrot cake']
friend_foods = my_foods[:]
如果不使用切片,friend_foods = my_foods 这种语法将新变量friend_foods关联到my_foods列表,这两个变量都指向同一个列表。
4.5 元组
不可变的列表被称为元组,元组里面的元素不可修改。
元组看起来犹如列表,但是元组定义时使用圆括号而不是方括号,但是元组访问时也是用方括号。
dimensions = (200, 50)
print(dimensions[0])
不能修改元组的元素,但是可以给存储元组的变量赋值,例如
dimensions = (200, 50)
dimensions[0] = 400 #error
dimensions = (400, 100)#success
4.6设置代码格式
用四个空格进行缩进
第5章 if语句
一个简单示例,bmw用全大写打印,其余的用首字母大写的形式打印
cars = ['audi', 'bmw', 'subaru', 'toyota']
for car in cars:
if car == 'bmw':
print(car.upper())
else:
print(car.title())
python中检查是否相等时区分大小写,
使用and检查多个条件,age_0 >= 21 and age_1 <=30
使用or检查多个条件,age_0 >= 21 or age_1 <= 15
要判断特定的值是否已包含在列表中,可使用关键字in。
requested_topping = ['mushrooms', 'onions', 'prieapple']
'mushrooms' in requested_topping
判断特定的值未包含在列表中,可使用关键字 not in
布尔表达式:game_active = True;
5.3if 语句
当if条件成立后,if语句后面所有缩进的代码都将被执行。
if elif else语句,注意不是C语言中那种else if,而是elif
5.4.2确定列表不是空的
if 列表名 如果列表为空返回False,如果列表非空则返回True.
第6章 字典
在python中,字典是一系列键-值对,例如
alien_0 = {'color' : 'green', 'points' : 5}
print(alien_0['color'])
print(alien_)['points'])
要往字典中添加新的键值对,直接赋值就可以添加。
修改字典中的值也是直接赋值。
使用delete将相应的键值彻底删除, delete alien_0['points']
6.3遍历字典
6.3.1遍历所有的键-值对
for name, language in favorite_languages.items(): #注意name和language中间有个逗号
print(name.title() + " 's favourite language is " +
language.title() + ".")
其中name和language为声明的两个变量,用于存储键-值对中的键和值,方法items()返回一个键-值对列表。
6.3.2遍历字典中的所有键
for name in favourite_language.keys():
print(name.title())
6.3.3按顺序遍历字典中的所有键
for name in sorted(favourite_languages.keys()):
print(name.title() + " , thank you for taking the poll.")
6.3.4遍历字典中的所有值
for language in favourite_languages.values():
print(languages.title())
如果想在最终的列表中不包含重复项,那么可以使用set剔除重复项
for language in set(favourite_languages.values()):
print(language.title())
6.4嵌套
可以在字典中嵌套列表,在列表中嵌套字典,在字典中嵌套字典。
第7章 用户输入和while循环
函数input()接受一个参数,向用户显示的提示或说明,然后等待用户输入一些文本,获取用户输入。使用函数input时,python将用户输入解读为字符串。
可以使用int()将数字的字符串表示转换为数值表示(其实就是强制类型转换),
height = input("how tall are you, in inches?")
height = int(height)
7.1.3求模运算符 将两个数相除,并返回余数。
7.2while循环简介
current_number = 1
while current_number <= 5:
break:和C语言一样,用于跳出循环,不仅仅是跳出while循环,也可以用于跳出前面介绍的for循环。
continue,和C语言一样,用于越过本次循环,
7.3 使用while循环来处理列表和字典
第8章 函数
8.1定义函数
def greet_user(username):
""" 显示简单的问候语 """
print("Hello, " + username.title() + "!")
使用def关键字来告诉python你要定义一个函数,紧跟在def greet_user(username):后面的所有缩进行构成了函数体,文档字符串用三个引号括起来,用来描述函数是做什么的,
8.2 传递实参
8.2.1 位置实参
实参和形参基于顺序进行关联,这种关联方式成为位置实参。
8.2.2关键字实参
其实就是传递实参时指定该实参时给哪个形参的,例如
def describe_pet(animal_type, pet_name):
""" 显示宠物的信息 """
print(" I have a " + animal_type + ".")
print(" My " + animal_type + "'s name is " + pet_name.title() + ".")
describe_pet(animal_type = 'hamster', pet_name = 'harry')
8.2.3默认值
def describe_pet(pet_name, animal_type='dog'):
8.3返回值
python中,函数声明时不用指明返回值,直接在调用时把函数赋值给一个变量得到返回值,例如
def get_formatted_name(first_name, last_name):
""" 返回整洁的姓名 """
full_name = first_name + ' ' + last_name
return full_name.title()
8.3.2让实参变成可选的
如果直接将列表作为函数实参,那么函数内部会修改该列表,如果将列表的副本(例如list_name[:])传递给函数,那么函数内部改变的是列表的副本,原来的列表丝毫不受影响。
8.5传递任意数量的实参
def make_pizza(*toppings):
""" 打印顾客点的所有配料 """
print(toppings)
形参名*toppings中的星号让python创建一个名为toppings的空元组,并将收到的所有值都封装到这个元组中,(不变的列表被称为元组)
8.5.2使用任何数量的关键字实参
def build_profile(first, last, **user_info):
""" 创建一个字典,其中包含我们知道的有关用户的一切 """
profile = {}
profile['first_name'] = first
profile['last_name'] = last
for key, value in user_info.items():
profile[key] = value
return profile
user_profile = build_profile('abert', 'einstein', location='princeton', field='physics')
print(user_profile)
形参**user_info中的两个星号让python创建一个名为user_info的空字典。函数调用时,location和field被赋值给key,princeton和physice被赋值给value.
8.6将函数存储在模块中
模块就是文件,其实就是把
8.6.1导入整个模块
某个函数写在另一个文件中,然后使用的时候把另一个文件倒入。
例如某个函数function_name是在一个module_name.py的模块中,我们要使用这个函数,那么
import module_name
module_name.function_name()
8.6.2导入特定的函数
from module_name import function_0, function_1, function_2
function_0()
这种导入方法,调用函数时就不用指定模块名字了,
8.6.3使用as给函数指定别名
from pizza import make_pizza as mp 这样后面就可以直接使用mp()代替make_pizza()
8.6.4使用as给模块指定别名
import pizza as p
p.make_pizza()
8.6.5导入模块中的所有函数
from pizza import *
使用*运算符可让python导入模块中的所有函数。这种方法一般不要采用,python可能遇到多个名称相同的函数或变量,进而覆盖函数,而不是分别导入所有函数。一般来说,要么只导入你需要使用的函数,要么导入整个模块并用句点表示法。
8.7函数编写指南
函数名字只使用小写字母和下划线
每个函数都应包含简要地阐述其功能的注释
给形参指定默认值时,等号两边不要有空格,
函数调用时的关键字实参,等号两边也不要有空格,
如果形参很多,导致函数定义的长度超过了79个字符,可在函数定义中输入左括号后按回车键,并在下一行按两次Tab键,
def function_name(
para_0, para_1, para2,
para3,para4, para5):
function body...
所有的import都应放在文件开头。
第9章 类
9.1.1 创建Dog类
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!")
在python中,首字母大写的名称指的是类,这个类定义中的括号是空的。
__init__的前后各有两个下划线,每当创建新的实例时,python都会自动运行__init__
self是一个指向实例本身的引用,类中的方法调用时都自动传递实参self.
在__init__函数中,形参self必不可少(因为python调用__init__创建实例时,将自动传入实参self),而且self必须位于其他形参的前面。
命名约定:我们通常可以认为首字母大写的名称(如Dog)指的是类,而小写的名称(如my_dog)指的是根据类创建的实例。
访问类中的属性,调用类中的方法都是用句点表示法。
9.3继承
一个类继承另一个类时,它将自动获取另一个类的所有属性和方法。
class ElectricCar(Car):
""" 电动汽车的独特之处 """
def __init__(selt, make, model, year):
""" 初始化父类的属性 """
super().__init__(make, model, year)
创建子类时,必须在括号内指定父类的名称。
super()是一个特殊的函数,帮助python将父类和子类关联起来,这行代码让python调用父类的方法__init__(),父类也成为超类,名称super因此而得名。
9.3.4重写父类的方法
在子类中定义与父类同名的方法,这样,python将忽略父类中的方法,而只关注子类中定义的方法。
9.3.5将实例用作属性
类的成员可是另一个类,
9.4导入类
可以将类存储在模块中,然后在主程序中导入所需的模块。
9.4.1导入单个类
假如Car类定义在car.py文件中,那么我们可以使用 from car import Car
9.4.3从一个模块中导入多个类
可以从一个模块中导入多个类,用逗号分隔,例如,from car import Car, ElectricCar
9.4.4导入整个模块
导入整个模块,再用句点表示法访问需要的类,
9.4.5导入模块中的所有类
from module_name import *
不推荐使用这种方法,如果需要从一个模块中导入很多类时,最好导入整个模块,并使用module_name.class_name语法来访问类,
9.6类编码风格
类名应该采用驼峰命名法,即将类名中的每个单词的首字母都大写,而不使用下划线,实例名和模块名都采用小写格式,并在单词之间加上下划线。
对于每个类,都应该紧跟在类定义后面包含一个文档字符串,简要描述类的功能。
每个模块也都应包含一个文档字符串,对其中的类可用于做什么进行描述。
第10章 文件和异常
10.1从文件中读取数据
10.1.1读取整个文件
with open('pi_digits.txt') as file_object:
contents = file_object.read()
print(contents)
无论是要打印文件还是读取文件,首先都要先打开文件,这样才能访问它
关键字with在不再需要访问文件后将其关闭,这样我们就不用自己用close()关闭文件了,python自己会在合适的时候自动将其关闭。
10.1.2文件路径
相对路径,
linux: 使用斜杠 with open ('text_files/filename.txt') as file_object: 注意有个冒号
windows:使用反斜杠 with open('text_filesfilename.txt') as file_object:
绝对路径
linux:
file_path = '/home/ehmatthes/other_files/text_files/filename.txt'
with open(file_path) as file_object:
windows:
file_path = 'C:Usersehmatthesother_files ext_filesfilename.txt'
with open(file_path) as file_object:
10.1.3逐行读取
file_name = 'pi_digits.txt'
with open(file_name) as file_object:
for line in file_object:
print(line)
10.1.4创建一个包含文件各行内容的列表
使用关键字with时,open()返回的文件对象只在with代码块内可用,如果要在with代码块外访问文件的内容,可在with代码块内将文件的各行存储在一个列表中,并在with代码块外使用该列表,
file_name = 'pi_digits.txt'
with open(file_name) as file_object:
lines = file_object.readlines()
for line in lines:
print(line.rstrip())
10.1.5使用文件的内容
读取文本文件时,python将其中的所有文件都解读为字符串,如果你读取的是数字,并要将其作为数值使用,就必须使用函数int()将其转换为整数,或使用函数float()将其转换为浮点数。
10.2写入文件
filename = 'programming.txt'
with open(filename, 'w') as file_object
file_object.write("I love programming")
'r' 读取模式; 'w'写入模式;'a' 附加模式; 'r+'读取和写入;省略模式实参,那么默认以只读模式打开。
如果要写入的文件不存在,函数open()将会自动创建,但是用'w'模式打开文件时,如果指定的文件已经存在,那么python将在返回文件对象前清空该文件。
python只能将字符串写入文本文件,要将数值数据存储到文本文件中,必须先使用函数str()将其转换为字符串格式。
10.2.2写入多行
函数write()不会在你写入的文本末尾添加换行符,因此如果想让每个字符串都单独占一行,需要在write()语句中包含换行符。
filename = 'programming.tx'
with open(filename, 'w') as file_object:
file_object.write("I love programming. ")
file_object.write("I love creating new games. ")
10.3异常
python使用try-except代码块处理异常
try:
print(5/0)
except ZeroDivisionError:
print("You can not divide by zero!")
try-except-else 如果发生异常,则执行except里面的代码,如果成功执行则执行else里面的代码
try:
answer = int(first_num) / int(second_num)
except ZeroDivisionError:
print("You can not divide by 0!")
else:
print(answer)
10.3.6 分析文本
方法split()根据一个字符串创建一个单词列表。它以空格为分隔符将字符串分拆成多个部分,并将这些部分存储到一个列表中,结果是一个包含字符串中所有单词的列表。
title = "Alice in Wonderland"
words = title.split()
得到的words是 ['Alice', 'in', 'Wonderland']
10.3.8失败时一声不吭
python有一个pass语句,可在代码块中使用他来让python什么都不要做。
try:
---snip---
except FileNotFoundError:
pass
else
---snip---
10.4存储数据
使用json.dump()存储数字列表
import json
numbers = [2, 3, 5, 7, 11, 13]
filename = 'numbers.json'
with open(filename, 'w') as f_obj:
json.dump(numbers, f_obj)
使用json.load()将列表读取到内存中
import json
filename = 'numbers.json'
with open(filename) as f_obj:
numbers = json.load(f_obj)
print(numbers)
第11章 测试代码
test_name_function.py
import unittest
from name_function import get_formatted_name
class NameTestCase(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()
1.首先我们导入模块unittest,
2.创建类,该类继承自unittest.TestCase
3.我们运行test_name_function.py时,所有test_开头的方法都将自动运行,
4.unittest.main()行让python运行这个文件中的测试。
运行结果
.
---------------------------------------------------
Ran 1 test in 0.000s
OK
第一行的句点表明有一个测试通过了,接下来的一行指出python运行了一个测试,消耗的时间不到0.001s,最后的OK表明该测试用例中的所有单元测试都通过了。
11.2 测试类
assertEqual(a, b) 核实a == b
assertNoEqual(a, b) 核实a != b
assertTrue(x) 核实x为True
asserFalse(x) 核实x为False
assertIn(item, list) 核实item在list中
assertNotIn(item, list) 核实item不在list中