Python3 入门笔记
为了做大一立项为了提升自身姿势水平需要在寒假先把 Python 学了...
由于会 C/C++,笔记采用对比方法辅助记忆。
操作系统:macOS 10.15
参考书籍:《Python编程:从入门到实践》,笔记目录也将参考该书目录
起步
macOS 10.15 自带 Python3,终端输入 python3
即可运行。
Sublime text 文本编辑器
变量和简单数据类型
Hello world
print("Hello world!")
注意:print
语句末尾自动换行
【与 C++ 不同】Python3 使用缩进来组织代码结构,而非大括号。
变量
命名规范:【和 C++ 类似】,不赘述。
尽量用小写变量名(下划线法),这是 Python3 的主流命名方式。
【与 C++ 不同】不用声明变量类型,Python3 解释器自己解释。
字符串
【与 C++ 不同】可以用 ""
或者 ''
括起字符串。(小心歧义)
设 str
是一个字符串:
str.title()
: 返回单词首字母大写,其余字母小写(不管以前是不是大写)的字符串str.upper()
和str.lower()
:返回全文大/小写的字符串str1 + str2
: 返回用加号拼接的字符串【和 C++ 的string
类似】- 制表符
\t
,换行符\n
【和 C++ 一样】 str.lstrip()
和str.rstrip()
和str.strip()
: 返回删除开头/末尾/两端空白的字符串str.replace(str1, str2)
:将字符串中的单词str1
全部替换成str2
str.split()
:以空格为分隔符把字符串拆成一个个单词,并返回包含这些单词的列表
Python3 视字符串非空为 True
数字
+
-
*
/
**
(乘方)str(a)
: 把数字(整型或浮点型)a
转换成字符串
【与 C++ 不同】在 Python3 中,输出 3/2
的值是 1.5
,即 Python3 将其理解为浮点数除法而非整除。
注释
用 #
标识。
列表 Lists
【与 C++ 的 vector 类似】
设 lst
是一个列表:
访问元素
定义列表:
lst = [a, b, c, d]
,其中a,b,c,d
等是列表的元素,类型可以不同打印列表:
print(lst)
(会将列表中的元素列出,括在方括号里)访问元素:
lst[3]
, 索引从 0 开始!!!【与 C++ 不同】支持负数索引,
-1
表示倒数第一个,-2
倒数第二个。更具体地,设列表共 \(x\) 个元素,则索引范围是 \([-x,x)\).
修改、添加、删除元素
- 修改:赋值就好了
lst.append(x)
: 在列表末尾添加元素x
lst.insert(idx, x)
: 在列表索引idx
处插入一个元素x
(插入后,x
的索引是idx
,其后的元素后移一格)del lst[3]
: 删除指定元素(删除后,其后元素前移一格)lst.pop()
: 弹出并返回最后一个元素lst.pop(idx)
: 弹出并返回指定元素lst.remove(x)
: 删除第一个值为x
的元素
组织列表
lst.sort()
和lst.sort(reverse = True)
: 对列表排序,永久性修改顺序sorted(lst)
和sorted(lst, reverse = True)
: 返回排序后的列表,但不改变列表原有顺序lst.reverse()
: 翻转列表,永久性修改顺序len(lst)
: 返回列表长度
遍历列表——for
语句
从头到尾遍历列表:
1 |
|
注意最后有个冒号 :
【与 C++ 不同】i
是列表元素,不是索引;循环结束后 i
停留为最后一个元素。
数值列表
range(l, r)
: 依次生成 \([l,r)\) 中的整数【类似于 C++ 的for(int i = l; i < r; i++)
】range(l, r, step)
: 指定步长为step
【类似于 C++ 的for(int i = l; i < r; i += step)
】list(range(l, r))
: 把range(l, r)
转换为列表min(lis)
和max(lis)
和sum(lis)
: 返回数值列表的最小值、最大值、和- 列表解析:
列表名 = [表达式 for循环]
,例如:lis = [value**2 for value in range(1,11)]
(有描述法定义集合之感)
列表切片
lis[l:r]
: 返回一个列表,元素依次是lis
列表的索引在 \([l,r)\) 内的元素省略
l
或r
则默认从头开始或到尾结束可以循环遍历列表切片:
for i in lis[l:r]:
复制列表:在切片中同时省略
l
和r
,即返回从头到尾的列表注意:复制列表应改写为:
lis2 = lis1[:]
,而非lis2=lis1
,后者lis1
和lis2
实质是同一个列表【类似 C++ 的引用】
元组 Tuples
元组就是元素值不可更改的列表。
定义元组
tpl = (a, b, c, d)
: 把列表定义中的方括号 []
改成圆括号 ()
即可
遍历元组
for i in tpl:
和列表一样
修改元组
元组中元素的值不能修改,但是元组变量本身可以被赋值。
例如:
1 |
|
上述代码合法。
if
语句
等号
==
,不等号!=
【和 C++ 一样】与
and
,或or
检查特定值是否包含在列表中:
x in lst
例如:
1
2
3lst = [1, 3, 6]
print(3 in lst)
print(4 in lst)分别输出
True
和False
检查特定值不在列表中:
x not in lst
if
语句:1
2if 条件测试:
do something注意最后有个冒号
:
if-else
语句:1
2
3
4if 条件测试:
do something
else:
do something注意
else
后面也有一个冒号:
if-elif-else
语句1
2
3
4
5
6if 条件测试:
do something
elif 条件测试:
do something
else:
do something检查列表是否为空:
1
2if lst:
do something以列表名为条件表达式,Python3 在列表为空时返回
False
,非空时返回True
。
字典 Dictionaries
字典是一系列 “键-值对”,可将任何 Python 对象作为值。
【类似于更高端版本的 C++ 的 map】
定义字典
1 |
|
花括号括起一系列键-值对,键与值之间冒号 :
分隔,键值对之间逗号 ,
分隔。
访问字典
dic['color']
: 字典名[键]
添加、修改、删除
- 添加:直接赋值即可(即使键本来不存在)。例如:
dic['x'] = 0
- 修改:直接赋值即可
- 删除:
del dic['points']
遍历字典
遍历所有键-值对:
1
2for k, v in favorite_languages.items():
do somethingk
和v
是自定义的变量名,可以更换成其他名称。方法
items()
返回键-值对列表。遍历所有键:
1
2for k in favorite_languages.keys():
do somethingk
是自定义的变量名。方法
keys()
返回键的列表,可省略(即for k in favorite_languages:
)由于
keys()
本质是个列表,各种对列表的操作也适用,例如:按顺序遍历所有键:
for k in sorted(favorite_languages.keys()):
检查某值是否在键中:
if 'catherine' in favorite_languages.keys():
遍历所有值:
1
2for v in favorite_languages.values():
do somethingv
是自定义的变量名。方法
values()
返回值的列表。去重:
for v in set(favorite_languages.values()):
嵌套
字典列表:列表的元素是字典,例如:
1
2
3
4alien_0 = {'color': 'green', 'points': 5}
alien_1 = {'color': 'yellow', 'points': 10}
alien_2 = {'color': 'red', 'points': 15}
aliens = [alien_0, alien_1, alien_2]字典中嵌套列表,例如:
1
2
3
4pizza = {
'crust': 'thick',
'toppings': ['mushrooms', 'extra cheese'],
}字典嵌套字典,例如:
1
2
3
4
5
6
7
8
9
10
11
12users = {
'aeinstein': {
'first': 'albert',
'last': 'einstein',
'location': 'princeton',
},
'mcurie': {
'first': 'marie',
'last': 'curie',
'location': 'paris',
},
}
用户输入
###input()
函数
1 |
|
其中,prompt
是显示在屏幕上的提示词,input()
函数返回一个字符串存储在变量 a
中,即用户的输入内容。
数值输入
int(x)
函数将字符串 x
转换成整数值。例如:
1 |
|
float(x)
函数将字符串 x
转换成浮点数值。
取模运算
a % b
例如:35 % 4 == 3
,-35 % 4 == 1
,35 % -4 == -1
,-35 % -4 == -3
【与 C++ 不同:负数对正数取模时返回正余数,而非像 C++ 那样返回负余数】
while
语句
while
语句:1
2while 循环条件:
do something注意最后有个冒号
:
break
和continue
【和 C++ 一样】
函数 Functions
定义与调用
1 |
|
传递实参
位置实参:实参位置与形参位置对应【和 C++ 一样】
关键字实参:例如:
1
2
3
4def pet(type, name):
print("My " + type + "'s name is " + name.title() + ".")
pet(name='harry', type='hamster')设定默认值:例如:
1
2
3
4def add(a, b=0):
print(a + b)
add(1)注意:形参列表中必须先列出无默认值的形参,再列出有默认值的形参
返回值
return
【和 C++ 一样】
可以 return
任何类型(包括列表、字典等)
传递列表
把列表名作为实参传过去即可。
在函数中修改列表可更改原列表【类似于 C++ 的传递数组实质是传递首地址】
不想修改原列表可传递切片,例如:
1
2
3
4
5
6
7def print_models(unprinted_designs, completed_models):
while unprinted_designs:
current_design = unprinted_designs.pop()
print("Printing model: " + current_design)
completed_models.append(current_design)
print_models(unprinted_designs[:], completed_models)
传递任意数量的实参
在形参前加星号
*
,Python3 会创建一个该形参名称的元组1
2def func(*tpl):
do something例如:
1
2
3
4
5def make_pizza(*toppings):
print(toppings)
make_pizza('pepperoni')
make_pizza('mushrooms', 'green peppers', 'extra cheese')与位置实参结合:位置实参在前,任意数量实参在后
例如:
1
2
3
4def make_pizza(size, *toppings):
print("\nMaking a " + str(size) + "-inch pizza with the following toppings:")
for topping in toppings:
print("- " + topping)任意数量的关键字实参:在形参前加
**
,Python3 会创建一个该形参名称的字典1
2def func(a, b, **c):
do something例如:
1
2
3
4
5
6
7
8
9def build_profile(name, **info):
profile = {}
profile['name'] = name
for key, value in info.items():
profile[key] = value
return profile
user = build_profile('jason', location = 'China', university = 'HITSZ')
print(user)
将函数存储在模块中
模块是扩展名为 .py 的文件,包含代码【类似于 C++ 的头文件】
导入整个模块
1
import pizza
调用时使用句点
.
,例如:1
pizza.make_pizza(16, 'green peppers')
导入特定函数
1
2from module_name import function_name
from module_name import function_0, function_1, function_2调用时无需使用句点
函数别名:
as
1
from module_name import function_name as fn
例如:
1
2
3from HelloWorld import say_hello as sh
sh()模块别名:
as
1
import module_name as mn
例如:
1
2
3import HelloWorld as HW
HW.say_hello()导入模块中所有函数:星号
*
1
from module_name import *
例如:
1
2
3
4from HelloWorld import *
say_hello()
say_bye()
所有 import
都放在程序开头【类似于 C++ 的 #include<>】
类 Classes
创建和使用类
以举例的方式说明如何创建类:
1
2
3
4
5
6
7
8
9class Dog():
"""a dog"""
def __init__(self, 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!")- 约定类的名称采用驼峰命名法
""" """
括起一段描述- 方法
__init__()
:创建实例时自动调用【类似于 C++ 的构造函数】 self
是__init__()
中必不可少的形参,且位于第一个,所有与类相关的方法都自动传入实参self
,它是一个指向实例自身的引用【类似于 C++ 的 *this】__init__()
中定义的两个变量前都有self.
,表明其可供类中所有方法使用
举例说明如何创建实例:
1
2
3my_dog = Dog('willie', 6)
print(my_dog.name.title())
my_dog.roll_over()访问属性和调用方法都采用句点
.
使用类和实例
给属性指定默认值:在
__init__()
中赋值即可,例如:1
2
3
4
5
6
7
8class Car():
def __init__(self, make, model, year):
self.make = make
self.model = model
self.year = year
self.odometer_reading = 0
my_new_car = Car('audi', 'a6', 2019)修改属性值:
直接修改:
1
2
3
4class Car():
# omit
my_new_car.odometer_reading = 100定义一个方法修改:
1
2
3
4
5
6
7
8
9
10class Car():
# omit
def update(self, mileage):
self.odometer_reading = mileage
def increase(self, mileage):
self.odometer_reading += mileage
my_new_car = Car('audi', 'a6', 2019)
my_new_car.update(30)
my_new_car.increase(100)
继承
一个类继承另一个类时,它自动获得另一个类的所有属性和方法;原有的类称为父类或超类(superclass),而新类称为子类。子类继承父类的属性和方法后,还可以定义自己的属性和方法。
举例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17class Car():
# omit
class ElectricCar(Car):
def __init__(self, make, model, year):
super().__init__(make, model, year)
self.battery_size = 70
def print_battery(self):
print(self.battery_size)
def update(self, mileage):
print("no!")
my_tesla = ElectricCar('tesla', 'model s', 2016)
my_tesla.increase(120)
print(my_tesla.odometer_reading)
my_tesla.print_battery()
my_tesla.update(10)- 定义子类时,括号里指定父类名称,
__init__()
接受创建父类所需的信息 super()
函数将父类和子类关联起来。super().__init__()
调用父类的方法__init__()
,使子类包含父类所有属性battery_size
和print_battery()
分别是子类特有的属性和方法update()
是父类的函数,在子类里重写了
- 定义子类时,括号里指定父类名称,
将实例作为属性:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16class Car():
# omit
class Battery():
def __init__(self, battery_size=70):
self.battery_size = battery_size
def print_battery(self):
print(self.battery_size)
class ElectricCar(Car):
def __init__(self, make, model, year, bat):
super().__init__(make, model, year)
self.battery = Battery(bat)
my_tesla = ElectricCar('tesla', 'model s', 2016, 80)
my_tesla.battery.print_battery()【类似于 C++ 的 struct 或 class 的嵌套】
导入类
假设上述 Car
,Battery
,ElectricCar
类都存储在 car.py
中:
导入单个/多个类:
1
2from car import Car
from car import Car, ElectricCar导入整个模块:
1
import car
访问模块内的类是需要使用句点
.
,例如:1
my_tesla = car.Electric('tesla', 'model s', 2016, 80)
导入模块内所有类:星号
*
1
from module_name import *
推荐用第二种方式导入并调用类。
Python 标准库
文件和异常 Files and Exceptions
读取文件
读取整个文件
1
2
3with open('pi_digits.txt') as file_object:
contents = file_object.read()
print(contents)open()
函数打开一个文件,返回表示文件的对象并存储在as
后的变量中- 关键字
with
使得 Python3 能够在合适的时候关闭文件,而不必手动调用close()
- 方法
read()
读取整个文件的内容并返回字符串,注意末尾有一个空行(可通过rstrip()
去掉)
文件路径
相对路径:从程序所在文件夹开始找
绝对路径:从根目录开始
逐行读取:用
for
语句1
2
3
4filename = 'pi_digits.txt'
with open(filename) as file_object:
for line in file_object:
print(line)注意每一行末尾都会有一个换行符(可通过
rstrip()
去掉)创建包含文件各行内容的列表
1
2
3
4
5filename = 'pi_digits.txt'
with open(filename) as file_object:
lines = file_object.readlines()
for line in lines:
print(line.rstrip())方法
readlines()
从文件读取每一行,并视为字符串将其存储在列表中,返回该列表
写入文件
1 |
|
open()
函数的第二个实参w
表示写入(自动创建或覆盖原内容),r
表示只读,a
表示附加(自动创建或添加到文件末尾),r+
表示读写。默认只读- 方法
write()
将字符串写入文件 write()
不会自动换行,要换行需写换行符\n
注:要写入数值,应先用 str()
将其转化为字符串
异常
异常是一种特殊对象,当 Python3 发生错误时会创建一个异常对象,若编写了处理异常的代码,程序将继续运行,否则将停止。
异常是使用 try-except
代码块处理的,该代码块告诉 Python3 出现异常时怎么办,程序也将继续运行。
try-except
代码块:1
2
3
4try:
print(5/0)
except ZeroDivisionError:
print("You can't divide by zero!")try-except-else
代码块:1
2
3
4
5
6
7
8
9
10
11
12
13print("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: ")
try:
answer = int(first_number) / int(second_number)
except ZeroDivisionError:
print("You can't divide by 0!")
else:
print(answer)一些异常:
ZeroDivisionError
FileNotFoundError
TypeError
ValueError
pass
语句:让 Python3 什么都不做
存储数据
使用模块 json
存储数据。
json.dump()
与json.load()
:1
2
3
4
5
6
7import json
numbers = [2, 3, 5, 7, 11, 13]
filename = 'numbers.json'
with open(filename, 'w') as f_obj:
json.dump(numbers, f_obj)1
2
3
4
5
6
7import json
filename = 'numbers.json'
with open(filename) as f_obj:
numbers = json.load(f_obj)
print(numbers)
测试 Testing
测试模块 unittest
单元测试、测试用例、全覆盖式测试
测试函数
要为函数编写测试用例,可先导入模块 unittest
以及要测试的函数,再创建一个继承 unittest.TestCase
的类,并编写一系列方法对函数行为的不同方面进行测试。
例如:
1 |
|
NamesTestCase
是继承unittest.TestCase
的一个类- 我们运行这个文件时,所有以
test_
打头的方法都将自动运行(方法名必须以test_
打头!) unittest.main()
让 Python3 运行这个文件的测试
unittest
的断言方法
方法 | 用途 |
---|---|
assertEqual(a, b) |
核实 a == b |
assertNotEqual(a, b) |
核实 a != b |
assertTrue(x) |
核实 a 为 True |
assertFalse(x) |
核实 a 为 False |
assertIn(item, list) |
核实 item 在 list 中 |
assertNotIn(item, list) |
核实 item 不在 list 中 |
测试类
与测试函数类似。
例如:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23import unittest
from survey import AnonymousSurvey
class TestAnonymousSurvey(unittest.TestCase):
"""针对AnonymousSurvey类的测试"""
def test_store_single_response(self):
"""测试单个答案会被妥善地存储"""
question = "What language did you first learn to speak?"
my_survey = AnonymousSurvey(question)
my_survey.store_response('English')
self.assertIn('English', my_survey.responses)
def test_store_three_responses(self):
"""测试三个答案会被妥善地存储"""
question = "What language did you first learn to speak?"
my_survey = AnonymousSurvey(question)
responses = ['English', 'Spanish', 'Mandarin']
for response in responses:
my_survey.store_response(response)
for response in responses:
self.assertIn(response, my_survey.responses)
unittest.main()方法
setUp()
:unittest.TestCase
类包含方法setUp()
,Python3 将先运行它,再运行各个以test_
打头的方法。例如:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25import unittest
from survey import AnonymousSurvey
class TestAnonymousSurvey(unittest.TestCase):
"""针对AnonymousSurvey类的测试"""
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_single_response(self):
"""测试单个答案会被妥善地存储"""
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()