Python 快速入门(第3版)8-10章 读书笔记

《Python 快速入门(第3版)》娜奥米·赛德

8.2 if-elif-else语句

Python中没有提供case语句。在大多数其它语言采用case或switch语句的场合,Python可以用串联的if...elif...elif...else结构来应对。如果遇到极少数棘手的场合,通常可用函数字典来解决

def do_a_stuff():
    #process a
def do_b_stuff():
    #process b    
def do_c_stuff():
    #process c
func_dict = {'a' : do_a_stuff,
             'b' : do_b_stuff,
             'c' : do_c_stuff }
x = 'a'
func_dict[x]()

例如,

def do_a_stuff(a,b):
    return a+b
def do_b_stuff(a,b):
    return a-b    
def do_c_stuff(a,b):
    return a*b
func_dict = {'a' : do_a_stuff,
             'b' : do_b_stuff,
             'c' : do_c_stuff }
x = 'a'
y = func_dict[x](333,555)
print(y) #输出888

8.3.1 range函数

对于给出的数字n,range(n)会返回0、1、2、……、n-2、n-1。因此,将列表长度(调用len函数)传入就会产生列表元素索引的序列。

>>> range(10)
range(0, 10)
>>> type(range(10))
<class 'range'>
>>> list(range(10))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>>

如果有两个数值参数,则第一个是结果序列的起始值,第二个是结果序列的结束值(不含)。

range函数的第三个可选参数,以便给出计数时的步进值。

>>> list(range(2,8))
[2, 3, 4, 5, 6, 7]
>>> list(range(2,8,3))
[2, 5]
>>>

8.3.4 for循环和元组拆包

下述代码在for关键字之后紧跟着用到了元组x,y,而不是平常的单个变量。

>>> somelist = [(1, 2), (3, 7), (9, 5)]
>>> result = 0
>>> for x, y in somelist:
...     result = result + (x * y)
...
>>> result
68
>>>

8.3.5 enumerate函数
enumerate函数返回的是元组(索引,数据项)
通过组合使用元组拆包和enumerate函数,可以实现同时对数据项及其索引进行循环遍历。

>>> x = [2, -3, 5, -7, -11]
>>> enumerate(x)
<enumerate object at 0x7f752b4ed090>
>>> list(enumerate(x))
[(0, 2), (1, -3), (2, 5), (3, -7), (4, -11)]
>>>
>>> for i,n in enumerate(x):
...     if n < 0:
...         print("Found a negative number at index:", i)
...
Found a negative number at index: 1
Found a negative number at index: 3
Found a negative number at index: 4
>>>

8.3.5 zip函数

zip函数可以从一个或多个可迭代对象中逐一读取对应元素,并合并为元组,直至长度最短的那个可迭代对象读取完毕

>>> a = [1, 2, 3, 4]
>>> b = ['a', 'b', 'c', 'd', 'e', 'f']
>>> z = zip(a,b)
>>> list(z)
[(1, 'a'), (2, 'b'), (3, 'c'), (4, 'd')]
>>>

8.4 列表和字典推导式

列表推导式的用法如下:
​​new_list = [expression1 for variable in old_list if expression2]

字典推导式的用法如下:
​​new_dict = {expression1:expression2 for variable in list if expression3}​​

生成器表达式
注意:除方括号的变化之外,生成器表达式还不返回列表。生成器表达式返回的是生成器对象,可用作for循环中的迭代器,这与range()函数的用途非常类似。
使用生成器表达式的优点是,不会在内存中生成整个列表。因此可生成任意大小的值序列,内存开销也很小。

动手题:推导式为了去除列表x中的负数,该用什么列表推导式来处理列表?
创建能返回1到100之间奇数的生成器。提示:奇数除以2后会有余数,余数可以用%2操作得到。
编写代码创建一个字典,键为11到15之间的数字,值为键的立方。

1.
>>> x_nonegative = [ a for a in x if a >=0 ]
>>> x_nonegative
[11, 666, 5, 223, 886]
>>>
>>>
>>> x_nonegative = [ x for x in x if x >=0 ]
>>> x_nonegative
[11, 666, 5, 223, 886]
>>>

2.
>>> gen = (i for i in list(range(100)) if i % 2 !=0)
>>> next(gen)
1
>>> next(gen)
3
>>> next(gen)
5
>>> next(gen)
7
>>>

3.
>>> { key:key**3 for key in list(range(11,16))}
{11: 1331, 12: 1728, 13: 2197, 14: 2744, 15: 3375}
>>>

8.6 布尔值和布尔表达式

操作符and和or将会返回对象
and操作符要么返回第一个为False的对象(表达式的计算结果),要么返回最后一个对象。
or操作符要么返回第一个为True的对象,要么返回最后一个对象。

大多数情况下,用到的都是==和!=,而不是is和is not。is和is not用来判断操作对象是否为同一个对象

9.4 局部变量、非局部变量和全局变量
nonlocal语句与global语句类似,它会让标识符引用最近的闭合作用域(enclosing scope)中已绑定的变量。

例:

如果想对函数之外的变量赋值,就必须将其显式声明为nonlocal或global。但如果只是要访问函数外的变量,则不需要将其声明为nonlocal或global。

9.6 lambda表达式

​​lambda parameter1, parameter2, . . .: expression​​

>>> deg_C2K = lambda deg_C: 273.15 + deg_C
>>> deg_C2K(32)
305.15
>>>

9.8 装饰器

def decorate(func):
    print("in decorate function, decorating", func.__name__)
    def wrapper_func(*args):
        print("Executing", func.__name__)
        return func(*args)
    return wrapper_func

def myfunction(parameter):
    print(parameter)

myfunction = decorate(myfunction)
myfunction("hello")

输出结果:
in decorate function, decorating myfunction
Executing myfunction
hello

装饰器(decorator)就是上述过程的语法糖(syntactic sugar),只增加一行代码就可以将一个函数包装到另一个函数中去。效果与上述代码相同。

装饰器由两部分组成:先定义用于包装或“装饰”其他函数的装饰器函数;然后立即在被包装函数的定义前面,加上“@”和装饰器函数名。

def decorate(func):
    print("in decorate function, decorating", func.__name__)
    def wrapper_func(*args):
        print("Executing", func.__name__)
        return func(*args)
    return wrapper_func

@decorate
def myfunction(parameter):
    print(parameter)

myfunction("hello")

输出结果:
in decorate function, decorating myfunction
Executing myfunction
hello

交互模式

>>> def decorate(func):
...     print("in decorate function, decorating", func.__name__)
...     def wrapper_func(*args):
...         print("Executing", func.__name__)
...         return func(*args)
...     return wrapper_func
...
>>> @decorate
... def myfunction(parameter):
...     print(parameter)
...
in decorate function, decorating myfunction
>>>
>>> myfunction("hello")
Executing myfunction
hello
>>>

10.2 编写第一个模块

mymath.py内容如下

"""mymath - our example math module"""
pi = 3.14159
def area(r):
    global pi
    return(pi * r * r)
>>> import mymath
>>> pi
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'pi' is not defined
>>>
>>> mymath.pi
3.14159
>>>

如果修改了磁盘中的模块文件,那么再次输入import命令并不会重新加载模块,这时要用到模块importlib的reload函数才可以。importlib模块为访问模块导入的后台机制提供了一个接口:

>>> mymath.pi
3.14159
>>> import mymath, importlib
>>> importlib.reload(mymath)
<module 'mymath' from '/root/mymath.py'>
>>> mymath.pi
3.14
>>>

当模块被重新加载(或第一次导入)时,其所有的代码都会被解析一遍。如果发现错误,则会引发语法异常。反之,如果一切正常就会创建包含Python字节码的.pyc文件,如mymath.pyc。

10.4 模块搜索路径
sys.path是Python的搜索模块的路径集,是一个列表

>>> sys.path
['', '/usr/local/python3/lib/python39.zip', '/usr/local/python3/lib/python3.9', '/usr/local/python3/lib/python3.9/lib-dynload', '/usr/local/python3/lib/python3.9/site-packages']
>>>

说明:sys.path的第一个元素为"",这会告知Python要在当前目录中查找模块。

10.5 模块内部私有名称

模块中下划线开头的标识符不能用from module import *导入。用前导下划线表示私有名称的约定,整个Python中都在使用,而不仅用在模块中。

例如 modtest.py内容如下

def f(x):
    return x
def _g(x):
    return x
a = 4
_b = 2

启动一个交互式会话测试

>>> from modtest import *
>>> f(3)
3
>>> _g(3)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name '_g' is not defined
>>>

注意:只有from <module> import *才会有这种行为。以下方式操作还是可以访问到_g和_b的:

启动一个交互式会话测试

>>> import modtest
>>> modtest._g(3)
3
>>> modtest._b
2
>>>

启动一个交互式会话测试

>>> from modtest import _g,_b
>>> _g(3)
3
>>> _b
2
>>>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值