python 学习记录,依据《Python 编程: 从入门到实践(第二版)》,本文章适合有编程经验的人阅读,将Python不同于其他现代编程语言的语法特意记录下来,有时间建议读一读原书,对于有现代编程经验的开发人员来说读起来的速度会非常快。
变量和简单数据类型
字符串
使用方法修改字符串的大小写
name = 'hello world'
print(name.title()) # Hello World
字符串方法 title()以首字母大写的方式显示每个单词,即将每个单词的首字母都改为大写。另外 upper()和 lower()方法可以将字符串全部改为大写或小写。
某些情况下希望合并几个字符串变成一个新的变量,这时模板字符串就很有必要。
hello = 'hello'
world = 'world'
print(f'${hello} ${world}') # hello world
该语法是 python3.6 引入的,如果你想在更早版本中使用,需要使用 format()方法
print('{} {}'.format(hello, world))
删除空白
你可以使用 rstrip()来删除字符串末尾的空白,同样 lstrip()来删除开头的空白,strip()来删除两边的空白。
数
整数
在 Python 中使用两个乘号表示乘方运算
print(3 ** 2) # 9
print(2 ** 4) # 16
浮点数和整数
将任意两个数相除时,结果永远是浮点数,即便这两个数都是整数且能整除。在其他任何运算中,如果一个操作数是整数,另一个操作数是浮点数,结果也总是浮点数。
数中的下划线
如果你想表示一个很大的数时,可以使用下划线将其中的数字分组,使其更清晰易读
large_num = 14_000_000_000_000
print(large_num) # 14000000000000
当你使用时,python 会自动忽略其中的下划线。
列表
列表由一系列按特定顺序排列的元素组成。
bicycle_list = ['trek', 'cannondale', 'redline', 'specialized']
print(bicycle_list)
如果这样,Python 会将列表变成一个字符串原封不动打印出来,很多时候这并不是我们希望的,所以需要更好的方式来访问列表元素。
访问列表元素
毫无疑问,类似绝大多数编程语言,Python 允许你通过索引来访问列表元素,同时也提供了一种特殊语法来快速访问最后的元素
print(bicycle_list[-1]) # specialized
print(bicycle_list[-2]) # redline
修改、添加和删除元素
我们只需要通过索引即可修改列表元素,着重介绍添加、删除元素
添加列表元素
在列表末尾添加元素
bicycle_list.append('renli')
在列表中插入元素
bicycle_list.insert(0, 'renli')
位于插入索引之后的元素,全部右移一个位置
删除列表元素
根据索引删除元素
del bicycle_list[0]
删除列表末尾的元素
pop()方法会返回你删除的元素,与 js 设计相同。
popped_bicycle = bicycle_list.pop()
print(popped_bicycle) # renli
实际上,可以使用 pop()来删除列表中任意位置的元素并返回该删除元素,只需要在括号中出传递你要删除元素的索引即可。
根据值删除元素
如果你只知道要删除元素的值,那么可以使用方法 remove()
bicycle_list.remove('redline')
组织列表
对列表永久排序
sort()方法能够让你较为轻松地对列表进行排序
bicycle_list = ['trek', 'cannondale', 'redline', 'specialized']
bicycle_list.sort()
print(bicycle_list) # ['cannondale', 'redline', 'specialized', 'trek']
同时也可以要求 sort 以相反的顺序排列
bicycle_list(reverse=True)
对列表临时排序
要保留列表原来的排列顺序,同时以特定的顺序呈现,可以使用 sorted()方法
bicycle_list = ['trek', 'cannondale', 'redline', 'specialized']
sorted_bicycle_list = bicycle_list.sorted()
print(bicycle_list)
print(sorted_bicycle_list)
打印结果,发现原数组并没有发生变化。
反转列表
如果你想将列表整个反转过来,可以使用 reverse()方法
确定列表的长度
使用 len()方法可以快速获悉列表的长度
print(len(bicycle_list)) # 4
操作列表
遍历整个列表
对于想要循环处理的问题,全部使用缩进,Python 就会认为你需要循环该行代码
bicycle_list = ['trek', 'cannondale', 'redline', 'specialized']
for bicycle in bicycle_list:
print(bicycle)
创建数值列表
Python 函数 range()让你能够轻松地生成一系列数。例如,可以像下面这样使用函数 range()来打印一系列数
for value in range(1, 5):
print(value)
结果会打印 1-4
使用 range()创建数字列表
如果需要将一组数转换为列表,可以使用 list()方法
nums = list(range(1, 5))
print(nums) # [1, 2, 3, 4]
而且还可以指定步长
nums = list(range(2, 11, 2))
print(nums) # [2, 4, 6, 8, 10]
在这个示例中,函数 range()从 2 开始数,不断加 2,直到超过 11 终止。
对数字列表执行简单的统计计算
有几个专门用于处理数字列表的 Python 函数。例如你可以轻松地找出列表的最大值,最小值和总和
nums = [1, 2, 3, 4, 5]
print(min(nums)) # 1
print(max(nums)) # 5
print(sum(nums)) # 15
列表解析
列表解析可以让你只需编写一行代码就生成比较复杂的列表。列表解析将 for 循环和创建新元素的代码合并成一行,并自动附加新元素。
squares = [value**2 for value in range(1, 11)]
print(squares) # 1, 4, 9, 16, 25, 36, 49, 64, 81, 100
使用列表的一部分
切片
bicycle_list = ['trek', 'cannondale', 'redline', 'specialized']
print(bicycle_list[0:3])
输出包含前三个自行车,同样不包含终止处的元素。如果没有指定第一个索引,Python 自动从列表开头开始切片,末尾同理。
复制列表
bicycle_list = ['trek', 'cannondale', 'redline', 'specialized']
anthor_bicycle_list = bicycle_list[:]
元组
有时你需要创建一系列不可修改的元素,那么元组就可以满足这种需求,Python 将不能修改的值称为不可变的,而不可变的列表被称为元组。
定义元组
元组使用小括号而非中括号来标识。
dimensions = (200, 50)
if 语句
条件测试
检查多个条件
不同于其他编程语言使用&和|号,Python 使用 and 和 or
检查特定值是否包含在列表中
bicycle_list = ['trek', 'cannondale', 'redline', 'specialized']
if 'trek' in bicycle_list:
print('trek is exist')
检查特定值是否不包含在列表中
bicycle_list = ['trek', 'cannondale', 'redline', 'specialized']
if 'trek' not in bicycle_list:
print('trek is not exist')
if 语句
if-elif-else 结构
如果需要判断不同的条件情况,就需要使用 if-elif-else 结构。
使用 if 语句处理列表
确定列表不是空的
list = []
if list:
print('list is not empty')
else:
print('list is empty')
Python 将在列表至少包含一个元素时返回 True,并在列表为空时返回 False
字典
一个简单的字典
person = {
'name': 'Joe Biden',
'age': 76
}
Python 中,字典是一系列键对值
使用字典
访问、添加、修改字典中的值
person = {}
person['age'] = 18
person['age'] = 20
print(person) # { age: 20 }
删除键值对
del person['age']
使用 get()来访问值
如果直接使用方括号来获取值,如果指定的值不存在就会报错,为了避免这样的错误,可以使用 get()来获取值,这样哪怕不存在也会给予一个默认值。同时你也可以设置如果出错之后需要返回的消息。
person = {}
print(person.get('age', 'No point value assigned.'))
遍历字典
for k, v in person.items():
print(f'key: {k}')
print(f'value: {v}')
遍历字典中的所有键
在不需要使用字典中的值时,方法 keys()就很有用。
for k in person.keys():
print(k)
以特定顺序返回元素
Python 默认通过插入顺序来遍历整个字典,但如果你想通过特定顺序来实现输出
# 剔除重复的值
for v in set(person.values()):
print(v)
# 对键进行排序
for k in sorted(person.keys()):
print(k)
遍历字典中的所有值
如果主要对字段包含的值感兴趣,可使用方法 values()来返回一个值列表,不包含任何键。
for v in person.values():
print(v)
用户输入
函数 input()的工作原理
函数 input()让程序暂停运行,等待用户输入一些文本。获取用户输入后,Python 将其赋给一个变量,以方便你使用。
message = input('Tell me something, and I will repeat it back to you: ')
print(message)
input()方法接受一个参数,即要向用户显示的提示或说明。
使用 int()来获取数值输入
如果你使用 input()方法获取用户输入时,Python 都默认视为字符串类型,而如果你想要数值的话可以使用 int()方法来转换成数值类型。
age = int(input('How old are you?: '))
if age >= 18:
print('You are audit')
else:
print('You are not audit')
函数
定义函数
def greet_user():
""" 文档字符串注释 """
print('Hello')
greet_user()
使用 def 关键字来声明这是一个函数定义,最后同样以冒号结尾
传递实参
除了通过位置传递参数外,还有其他方式可以传递实参。
关键字实参
def greet_user(name, greet):
print(f'Hello {name}, {greet}')
greet_user(greet='Good Morning', name='Biden')
关键字实参的顺序无关紧要,因为 Python 知道各个值应该赋给哪个形参。
默认值
可以给形参指定默认值。
def greet_user(name, greet='Good Morning'):
print(f'Hello {name}, {greet}')
传递任意数量的实参
如果你预先不知道函数需要接受多少个实参,Python 允许函数从调用语句中收集任意数量的实参。
def make_pizza(*toppings):
print(toppings)
make_pizza('mushrooms', 'green peppers', 'extra cheese')
参数*toppings 中的星号是让 Python 创建一个名为 toppings 的空元组,并将收到的所有值都封装到这个元组中。
结合使用位置实参和任意数量实参
如果需要函数接受不同类型的实参,必须在函数定义中将接纳任意数量实参的形参放在最后。Python 会先匹配位置实参和关键字实参,再将余下的实参都收集到最后一个形参中。
使用任意数量的关键字实参
def user_profile(first_name, last_name, **user_info):
user_info['first_name'] = first_name
user_info['last_name'] = last_name
return user_info
user_info = user_profile('albert, 'einstein', location='princeton', field='physics')
形参**user_info 中的两个星号让 Python 创建一个名为 user_info 的空字典,并将所有收到的名称值对都放到这个字典中。
将函数存储在模块中
你可以将函数存储在称为模块的独立文件中,再将模块导入到主程序中。import 语句允许在当前运行的程序文件中使用模块中的代码。
导入整个模块
import pizza
pizza.make_pizza(16, 'pepperoni')
pizza 模块文件只有一个 make_pizza 函数,你不必关注其中细节,只需要像这样导入即可使用该模块文件的所有函数。Python 会将该文件中所有函数都复制到这个程序中。
导入特定的函数
from pizza import make_pizza, dine_pizza
pizza = make_pizza('mushrooms', 'pepperoni')
dine_pizza(pizza)
给函数指定别名
from pizza import make_pizza as pizza
pizza(16, 'pepperoni')
给模块指定别名
import pizza as p
p.make_pizza(16, 'pepperoni')
导入模块中的所有函数
from pizza import *
make_pizza(16, 'pepperoni')
类
创建和使用类
class Dog:
def __init__(self, name, age):
self.name = name
self.age = age
def sit(self):
print(f'{self.name} is now sitting.')
def roll_over(self):
print(f'{self.name} rolled over.')
dog = Dog('Willie', 6)
print(dog.name)
print(dog.age)
print(dog.sit())
使用 class 关键字创建了一个 Dog 类,init()方法每次根据该类创建新的实例时都会被调用。形参 self 必不可少,并且必须位于其他形参的前面。当创建实例时,将自动传入实参 self。
继承
class Car:
def __init__(self, make, model, year):
self.make = make
self.model = model
self.year = year
def get_descriptive_name(self):
return f'{self.year} {self.make} {self.model}'
class ElectricCar(Car):
def __init__(self, make, model, year):
""" 初始化父类的属性 """
super().__init__(make, model, year)
tesla = ElectricCar('tesla', 'model s', 2019)
print(tesla.get_descriptive_name())
- 创建子类时,父类必须包含在当前文件中,且位于子类前面。
- 定义子类时,必须在圆括号内指定父类的名称。
- 方法init()接受创建 Car 实例所需的信息。
super()能够让你调用父类的方法
重写父类的方法
你可以在子类中随意重写父类已有的方法,这样当调用子类的方法时会自动忽略掉父类的方法。
Python 标准库
Python 标准库是一组模块,安装的 Python 都包含它。下面使用其中一个模块 random 中的 randint()。它将两个整数作为参数,并随机返回一个位于这两个整数之间(包含)的整数。
from random import randint, choice
print(randint(1, 6)) # 3
""" 传递一个列表或元组,随机返回其中的一个参数 """
print(choice('charles', 'martina', 'michael', 'florence', 'eli')) # florence
文件和异常
从文件中读取数据
读取整个文件
with open('pi_digits.txt') as file_object:
contents = file_object.read()
# 每读一行文件会自动在后面换行,所以文件末尾会多一行空白,使用rstrip()可以删除右侧空白
print(contents.rstrip())
在同级的根目录中有一个文本文件,现在我们要读取这个文件。open()表示要打开文件,接收一个参数即要打开文件的名称。Python 在当前执行文件所在的目录中查找指定文件。open()返回一个对象,这里将该对象赋给了 file_object 供以后使用。
with 表示在不需要访问文件后将其关闭。也可以调用 close()关闭文件,但这样做时,如果程序存在 bug 导致方法 close()未执行,文件将不会关闭。未妥善关闭文件可能导致数据丢失或受损。并非在任何情况下都能轻松确定关闭文件的恰当实际,但通过使用前面所示的结构,可以把关闭权交给 Python 处理:你只管打开文件,并在需要时使用它,Python 自会在合适的时候自动将其关闭。
逐行读取
with open('files/pi_digits.txt') as file_object:
for line in file_object:
print(line.rstrip())
创建一个包含文件各行内容的列表
使用关键字 with 时,open()返回的文件对象只能在 with 代码块内可用。如果要在 with 代码块歪访问文件和内容,可在 with 代码块内将文件的各行存储在一个列表中,并在 with 代码块外使用该列表
with open('pi_digits.txt') as file_object:
lines = file_object.readlines()
for line in lines:
print(line.rstrip())
写入文件
写入空文件
with open('pi_digits.txt', 'w') as file_object:
file_object.write('I love programming.')
open()第一个实参要打开这个文件,第二个实参’w’表示要以写入模式打开这个文件。打开文件时,可以指定’r’读取模式,'w’写入模式,'a’附加模式和’r+'读写模式。如果要写入的文件不存在,open()函数会自动创建它,如果已存在,Python 将在返回文件对象前清空该文件的内容。注意 write()函数不会自动在写入的文本末尾添加换行符,如果你需要换行,请注意要自己添加换行符。
附加到文件
如果要给文件添加内容,而不是覆盖原有的内容,可以以附加模式打开文件。以附加模式打开文件时,Python 不会再返回文件对象前清空文件的内容,而是将写入文件的行添加到文件末尾。如果指定文件不存在,Python 将为你创建一个空文件。
异常
每当发生让 Python 不知所措的错误时,它都会创建一个异常对象。如果你编写了处理该异常的代码,程序将继续运行;如果未对异常进行处理,程序将停止并显示 traceback,其中包含有关异常的报告。
异常是使用 try-except 代码块处理的。try-except 代码块让 Python 执行指定的操作,同时告诉 Python 发生异常时怎么办。
处理 ZeroDivisionError 异常
来看一个简单的错误,不能用数除以 0,所以可以捕获这种错误
try:
print(5/0)
except ZeroDivisionError:
print('You can\'t divide by zero')
使用异常避免崩溃
发生错误时,如果程序还有工作尚未完成,妥善地处理错误就尤其重要。这种情况经常会出现在要求用户提供输入的程序中;如果程序能够妥善地处理无效输入,就能再提示用户提供有效输入,而不至于崩溃。
else 代码块
依赖 try 代码成功执行的代码都应放在 else 代码块中
try:
answer = 5 / 0
except ZeroDivisionError:
print('You can\'t divide by 0')
else:
print(answer)
让 Python 还是执行 try 代码块中的除法运算,这个代码块只包含可能导致错误的代码。依赖 try 代码块成功执行的代码都放在 else 代码块中。在本例中,如果除法运算成功,就是用 else 代码块来打印结果。
处理 FileNotFoundError 异常
使用文件时,如果查找的文件找不到,就会报该错误。
分析文本
有时候你或许需要分析整个文本文件,比如分析一本书包含多少单词
file_name = 'Alice in Wonderland.txt'
try:
with open(file_name, encoding='utf-8') as alice:
contents = alice.read()
except FileNotFoundError:
print(f'sorry, the file {file_name} does not exists')
else:
# split()以空格为分隔符分拆成多个部分,最后返回一个列表
words = contents.split()
print(f'The file {file_name} has about {len(words)} words.')
静默失败
有时候并非每次捕获到异常都需要告诉给用户,而是希望程序在发生异常时保持沉默,就像什么都没有发生一样继续运行。要让程序静默失败,可以像通常那样编写 try 代码块,但在 except 代码块中明确地告诉 Python 什么都不要做。
file_name = 'Alice in Wonderland.txt'
try:
with open(file_name, encoding='utf-8') as alice:
contents = alice.read()
except FileNotFoundError:
# print(f'sorry, the file {file_name} does not exists')
pass
else:
# split()以空格为分隔符分拆成多个部分,最后返回一个列表
words = contents.split()
print(f'The file {file_name} has about {len(words)} words.')
现在,出现异常时将执行 expect 代码块中的代码,但什么都不会发生。
存储数据
一种简单的方式就是使用 json 模块来存储数据
使用 json.dump()和 json.load()
import json
numbers = [1, 2, 3, 4, 5]
with open('numbers.json', 'w') as file_object:
# 将numbers数组写入到json文件中
json.dump(numbers, file_object)
with open('numbers.json') as file_object:
numbers = json.load(file_object)
print(numbers)