Python 6-8章
tags: Python
Learning Note
第6章 抽象
-
6.3 创建函数
1. `callabel()`可以测试函数能否调用。(返回True/False)(3.0得用`hasattr(func, __cal__)`代替)
2. 使用`def`语句定义函数-
6.3.1 记录函数
直接写上字符串,比如在def
语句后面,称为文档字符串。
可以使用内建help
得到关于函数的信息,包括文档字符串。 -
6.3.2 并非真正函数的函数
return
起到结束函数的作用。
-
6.3.1 记录函数
-
6.4 参数魔法 这正是Python的魅力所在!
- 6.4.1 值从哪里来(实参与形参)
-
6.4.2 我能改变参数吗
这里有一篇写得不错的文章:Python的函数参数传递:传值?引用? -
6.4.3 关键字参数和默认值
关键字参数:参数很多的时候,参数的顺序很难记住,可以提供参数的名字。
默认值:同C一样,定义函数时可以为参数提供默认值。 -
6.4.4 收集参数
收集参数:用*+参数名
收集其余的位置参数为一个元组。(没有就是一个空元组)
关键字参数:**+参数名
收集有关键字的参数,得到一个字典。普通参数和关键字参数可以联合使用。
-
6.4.5 反转过程
函数收集的逆过程,在调用而不是在定义时使用。
同样字典也可以用def add(x, y): return x + y
params = (1, 2)
add(*params)**
翻转
这里的拼接Splicing不是很懂,mark下
-
6.5 作用域
变量可以看做是值的名字,然变量-所对应的值是个”不可见“的字典。内建的vars
函数可以返回这个字典。
这种“字典”就是作用域。scope = vars()
一般来说,vars所返回的字典是不能修改的,结果是未定义的,可能得不到想要的结果
可以直接引用全局变量。但最好还是用global
访问,如果内外作用域变量名重叠了,可以用globals()['parameter']
获取。
作用域是可以嵌套的。这里有一个闭包的概论,闭包是一个包含有环境变量取值的函数对象。环境变量取值被保存在函数对象的__closure__
属性中。关于闭包具体见这篇博文:Python 学习入门(25)—— 闭包 -
6.6 递归
自身调用自身。
“函数式编程”方面的函数:map、filter 和 reduce 函数(3.0中被移到 functools 模块中)标准库中的bisect模块可以非常有效地实现二元查找。
lambda
:匿名函数。map
:将序列中的元素全部传递给一个函数。list(map(str,range(10)))
filter
:基于一个返回布尔值的函数对元素进行过滤。list(filter(lambda x:x.isalnum(), seq))
reduce
:对一个序列的每个项迭代调用函数。它会将序列的两个元素与给定的函数联合使用,并且将它们的返回值和第3个元素继续联合使用,直到整个序列处理完毕。reduce(lambda x,y:x+y,numbers)
这边有一篇关于Python的函数式编程的简单介绍:python的函数式编程玩法+年末小感
第7章 更加抽象
-
7.1 对象的魔力
这书类都没讲竟先讲然这些特性,真太挫,不想多说 仨特性:多态 封装 继承 -
7.2 类和类型
- 7.2.1 类到底是什么 超类(superclass)就相当于c++里面的父类或基类。
-
7.2.2 创建自己的类 在模块或脚本开始的地方放置语句
__metaclass__
表示新式类。
= type关于
new_sytle class
详见啄木鸟社区的译文:python中的 new-style class 及其实例详解class语句会在函数定义的地方创建自己的命名空间
self是对于对象自身的引用如果知道foo是Person的实例的话,还可以把foo.greet()看做Person.greet(foo)方便的简写
-
7.2.3 特性、函数和方法
方法(更专业一点可称为绑定方法)将它们的第一个参数绑定到所属的实例上,因为这个参数可以不必提供。
self 参数并不取决于调用方法的方式。
在类的内部定义中,双下划线开始的名字被“翻译”成前面加下划线和类名的形式。 -
7.2.4 类的命名空间
类作用域的对象可以被所有实例访问。
重新绑定里面的特性会屏蔽类范围内的变量。 -
7.2.5 指定超类
claass A(B): ...
,B是A的超类,A是B的子类。 子类正常会重写超类的方法。 -
7.2.6 调查继承
issubclass
函数:查看一个类是否是另一个的子类。isinstance
函数:检查一个对象是否是一个类的实例。__bases__
特性:想要知道已知类的基类。__class__
:查看一个对象属于哪个类。
如果是新类的话,可以用type
函数来查看实例的类。 -
7.2.7 多个超类
多重继承,注意:先继承的类中的方法会重写后继承的类中的方法。
MRO(Method Resolution Order,方法判定顺序):查找给定方法或者特性时访问超类的顺序。 -
7.2.8 接口和内省
检查所需方法是否已经存在:hasattr(obj, 'method')
检查特性是否可调用:callable(getattr(obj, 'method', None))
(在3.0中可以使用hasattr(x, '__call__')
来代替callable(x)
)__dict__
特性:查看对象内所以存储的值。
第8章 异常
-
8.1 什么是异常
每个异常都是一些类的实例,这些实例可以被引发,并且可以用很多种方法进行捕捉,使得程序可以捉住错误并且对其进行处理,而不是让整个程序失败。 -
8.2 按自己的方式出错
-
8.2.1 raise语句
可以使用一个Exception的子类或者实例参数调用raise语句。
可以用dir(exceptions)
查看内建的异常。(需要import exceptions
) -
8.2.2 自定义异常类
class SomeCustomException(Exception): pass
-
8.2.1 raise语句
-
8.3 捕捉异常
try/except 异常
实现。
如果要传递异常,可以使用如果没有捕捉到异常,它会被“传播”到调用的函数中。如果那里依然没有捕获,这写异常就会“浮”到程序的最顶层。
raise
-
8.4 不止一个except子句
try/expect 异常
可以附带多个expect -
8.5 用一个块捕捉两个异常
try/expect (...)
将异常作为元组放进去 -
8.6 捕捉对象
捕捉产生的异常对象:try/ except (...), e
(3.0是as e
) -
8.7 真正的全捕捉
try/ expect
可以捕捉全部异常。注意:这样捕捉所有异常是危险的,因为它会隐藏所有程序员未想到并且未做好准备处理的错误。使用except Exception,e会更好,或者对异常对象e进行一些检查
-
8.8 万事大吉
try /expect /else
进行没有异常情况的处理。
下面是一个简单计算除法的代码:while True: # 如果出错必须重新输入,否则无法跳出循环
try:
x=input('Enter the first number: ')
y=input('Enter the second number: ')
print(int(x)/int(y))
except Exception as e : # 如果出错了,打印错误信息
print(e)
print('Invalid input,please try again')
else: # 计算过程没有异常,跳出
break -
8.9 最后
try/except/else/finally
:无论是否发生异常情况,都需要执行一些清理工作。(如通信过程) - 8.10 异常和函数
-
8.11 异常之禅
有时候用异常会比if/else
效率快。