读《python语言及其应用》做的笔记
第四章
python用缩进来区分代码段。
目的:了解python中的代码结构,[判断if, 循环while, 迭代(for, zip)],4种推导式,3种参数,*,**收集参数(收集位置参数,关键字参数),生成器,装饰器,闭包,异常等概念。
外壳, 代码结构
用代码缩进来区分代码块结构,避免输入太多的花括号和关键字。
python使用空白来区分代码结构。
使用#注释,当前行
python没有多行注释符号。
使用\连接
1,使用if , elif和else进行比较
if和else是python用来声明判断条件是否满足的语句。
判断语句之后要缩进。
在python中,代码缩进决定了if和else是如何配对的。
and or not 直接用原文。 布尔值。
2,使用while进行循环
break跳出循环
continue跳到循环开始
循环外是用else
while count <= 5:
conut ++
while True:
stuff = input("String to capitalize[type q to quit]:")
if stuff == "q":
break
print(stuff.capitalize())
else :
print("normoal quit!")
3,使用for迭代
for rabbit in rabbits:
print(rabbit)
元组,列表,字符串,字典,集合都是python中可迭代的对象。
字符串迭代一次会产生一个字符,字典返回字典中的键,其他都是产生一项。
如果想对字典的值进行迭代,可以使用字典的values()函数。
for value in accusation.values():
print(value)
为了以元组的形式返回键值对,可以使用字典的items()函数。
for item in accusation.items()
print(item)
#元组只能初始化一次,不可变。对于调用函数items()返回的每一个元组,将第一个返回值(键)
赋给card, 第二个返回值(值)赋给contents。
使用break,continue, else同while
使用zip()并行迭代
通过zip()函数对多个序列进行并行迭代
zip()函数在最短序列“用完”时就会停止,最长的就可能无法填充列表,除非人工干预。
eg:
1)for day, fruit, drink, dessert in zip(days, fruits, drinks, desserts):
2)list( zip(english, french))
配合dict()和zip()函数的返回值就可以得到一个微型的英法字典
使用range()生成自然数序列
返回特定区间的自然数序列,不需要创建和存储复杂的数据结构
用法类似于使用切片:range(start、stop、step)。而start的默认值为0,。唯一要求的参数是stop,step的默认值是1,也可以反向创建序列,则默认值为-1.
4,推导式
1)列表推导式
简单的
python代码:[expression for item in iterable]
eg:
number_list = [number for number in range(1, 6)]
有条件的
python代码:[expression for item in iterable if condition]
eg:
a_list = [number for number in range(1, 6) if number % 2 == 1]
多个for的python代码:
eg:
cells = [(row, col) for row in rows for col in cols]
另外,在对cells列表进行迭代时可以通过元组拆封将变量row 和 col的值分别取出:
eg:
for row, col in cells:
2)字典推导式
最简单的:{key_expression: value_expression for expression in iterable}
eg:
word = 'letters'
letter_counters = {letter : word.count(letter) for letter in word}
-> 进一步化简
letter_counters = {letter : word.count(letter) for letter in set(word)}
3)集合推导式
python代码:{expression for expression in iterable}
eg:
a_set = {number for number in range(1, 6) if number % 2 == 1}
4)生成器推导式
元组是没有推导式的,圆括号之间的是生成器推导式,它返回的是一个生成器对象,它是将数据传给迭代器的一种方式。
5,函数
前面都是小块,处理微小任务,要复用这些代码,就把大型代码组成成可管理的小代码段。
可以用函数做如下两件事:
1)定义函数
2)调用函数
def 函数名 带有函数参数的圆括号 :
下面需要缩进
eg:
def do_somgthing(有参/无参):
位置参数
最熟悉的类型是位置参数,传入参数的值是按照顺序依次复制过去的。
缺点:必须记住每个位置的参数的含义。
关键字参数
为了避免位置参数带来的错乱,调用参数时可以指定对应参数的名字,甚至可以采用与函数定义不同的顺序调用。
eg:
def meun(wine, entree, dessert)
return {'wine': wine, 'entree': entree, 'dessert': dessert}
调用: 关键字参数
meun(entree = 'beff', dessert = 'bagel', wine = 'bordeaux')
将两种参数混合起来:首先,实例化参数wine,然后对参数entree和dessert使用关键字参数的方式。
menu('frontenac', dessert = 'flan', entree = 'fish')
如果同时出现两种参数形式,首先应考虑的是位置参数。
指定默认参数
当调用方没有提供对应的参数值时,可以指定默认参数值。
听起来很普通的特性实际上特别有用。
def menu(wine, entree, dessert = 'pudding') #默认参数指定
return {'wine': wine, 'entree': entree, 'dessert': dessert}
调用不带dessert参数的函数menu():
menu('chardonnay', 'chicken')
默认参数值在函数定义时已经计算出来,而不是在程序运行时。
使用*收集位置参数
py没有指针概念。
当参数被用在函数内部时,星号将一组可变数量的位置参数集合成参数值得元组。
无参数调用函数,则什么也不返回。
给函数传入的所有参数都会以元组的形式返回输出。
对于print()等接受可变数量的参数特别适用
使用**收集关键字参数
使用两个*可以将参数收集到一个字典中,参数的名字是字典的键,对应参数的值是字典的值。
eg:
def print_kwargs(**kwargs):
print('Keyword arguments:', kwargs)
文档字符串
三元引号,多好字符串
''' '''
一等公民:函数
python中一切皆对象!
内部函数
可以在函数中定义另外一个函数
闭包
内部函数可以看做是一个闭包。闭包是一个可以由另一个函数动态生成的函数,并且可以改变和存储函数外创建的变量的值。
匿名函数:lambda()函数
lambda函数是用一个语句表达的匿名函数,可以用来代替小的的函数。
6,生成器
生成器是用来创建python序列的一个对象。使用它可以迭代庞大的序列,且不需要再内存中创建和存储整个序列。
通常,生成器是迭代器产生数据的,前面用过range()。
每次迭代生成器时,它会记录上一次调用的位置,并且返回下一个值。
这一点和普通的函数是不一样的,一般函数都不记录前一次调用,而且都会在函数的第一行开始执行。
如果想创建一个比较大的序列,使用生成器推导的代码会很长,这时可以尝试写一个生成器函数。
生成器函数和普通函数类似,但是它的返回值使用yeild语句声明而不是return。
eg:
def my_range(first = 0, last = 0, step = 1):
number = first
while number < last:
yeild number
number += step
ranger = my_range(1, 5)
ranger
<generator object my_range at 0x101a0a168>
对这个生成器进行迭代
for x in ranger
print(x)
7,装饰器
有时需要在不改变源码的情况下修改已经存在的函数。
装饰器实质上是一个函数。他把一个函数作为输入并且返回另外一个函数。
在装饰器中通常使用下面这些python技巧:
1)*args 和 **kwargs
2)闭包
3)作为参数的函数
8,命名空间和作用域
一个名称在不同的使用情况下可能指代不同的事物。
每一个函数定义自己的命名空间。如果在主程序main中定义一个变量x,在另外一个函数中也定义x变量,两者指代的是不同的变量。
但是,需要的话,可以通过多种方式获取其他命名空间的名称。
关键字:global
python提供了两个获取命名空间内容的函数:
1)locals()返回一个局部命名空间内容的字典。
2)globals()返回一个全局命名空间内容的字典。
eg:
animal = 'fruitbat'
def change_local():
animal = 'wombat' #局部变量
print('locals:', locals())
函数change_local()的局部命名空间只含有局部变量animal。
全局命名空间含有全局变量animal以及其他一些东西。
名称中_和__的用法
__是python保留用法,用户自定义变量不得使用。
function.__doc__:
9,使用try和except处理错误
在一些编程语言中,错误是通过特殊的函数返回值指出的,而python使用异常,他是一段只有错误发生时执行的代码。
try:
short_list[position]
except:
print('xxxxx')
try中的代码段被执行,如果存在错误,抛出异常,执行except代码,否则跳过。
适用于任何异常类型。
一个异常是一个类,即类Exception的一个子类。
eg:
class UppercaseException(Exception)
pass
即使没有定义UppercaseException的行为,也可以通过继承其父类Exception在抛出异常时输出错误提示。