函数
def name(x):
If x>=0:
Return x
Else:
Return -x
空函数
def nop():
Pass
占位符
函数返回多个值 本质上 是多个变量可以用时接受一个tuple,按位置赋给对应的值
默认参数 (简化 降低调用难度)
要求:必选参数在前,默认参数在后 必须指向不变对象
可变参数
*nums表示把nums这个list的所有元素作为可变参数传进去
关键字参数(拓展函数 如果调用者愿意提供更多参数 也能接收)
>>> extra = {'city': 'Beijing', 'job': 'Engineer'}
>>> person('Jack', 24, **extra)
name: Jack age: 24 other: {'city': 'Beijing', 'job': 'Engineer'}
命名关键字参数
*特殊分隔符 *后面的参数被视为命名关键字参数
命名关键字参数必须传入参数名
参数组合
顺序 :必选参数 默认参数 可变参数 关键字参数 命名关键字参数
*args是可变参数,args接收的是一个tuple;
**kw是关键字参数,kw接收的是一个dict。
递归函数
针对尾递归优化的语言可以通过尾递归防止栈溢出。尾递归事实上和循环是等价的,没有循环语句的编程语言只能通过尾递归实现循环
传入函数(高阶函数)
def add(x, y, f):
return f(x) + f(y)
1.Map 把f(x)作用在list的每个元素并把结果生成一个新的list 抽象了运算规则
2.Reduce 把结果继续和序列的下一个元素做累积计算
3.filter 根据返回值TRUE或者FALSE保留还是丢弃 筛选
Q:def is_odd(n):
return n % 2 == 1
list(filter(is_odd, [1, 2, 4, 5, 6, 9, 10, 15]))
筛选功能
求素数。。。
匿名函数
Lambda 限制是只能有一个吧表达式 不用写return 返回值就是表达式结果
装饰器(动态增加功能) 语法糖
函数作为变量传入其他函数,本身作为返回值
decrator输入和输出都是函数的函数(输入一定 输出不一定)
带参数的decorator多了一次等价调用
用dec对象对a装饰等价于a=dec(a)就是将a作为参数传给dec 返回值回赋给a
偏函数
参数太多时,functools.partial可以把一个函数的某些参数给固定住(也就是设置默认值),返回一个新的函数,调用这个新函数会更简单。
模块
Python代码集合
作用域
正常的函数和变量名是公开的(public),可以被直接引用,比如:abc,x123,PI等;
类似__xxx__这样的变量是特殊变量,可以被直接引用,但是有特殊用途,比如上面的__author__,__name__就是特殊变量,hello模块定义的文档注释也可以用特殊变量__doc__访问,我们自己的变量一般不要用这种变量名;
类似_xxx和__xxx这样的函数或变量就是非公开的(private),不应该被直接引用,比如_abc,__abc等;
面向对象编程
类(创建实例的模板)和实例(具体的对象)
继承可以把父类的所有功能都直接拿过来,这样就不必重零做起,子类只需要新增自己特有的方法,也可以把父类不适合的方法覆盖重写。
获取对象信息
假设我们希望从文件流fp中读取图像,我们首先要判断该fp对象是否存在read方法,如果存在,则该对象是一个流,如果不存在,则无法读取。hasattr()就派上了用场。
请注意,在Python这类动态语言中,根据鸭子类型,有read()方法,不代表该fp对象就是一个文件流,它也可能是网络流,也可能是内存中的一个字节流,但只要read()方法返回的是有效的图像数据,就不影响读取图像的功能。
实例属性(各个属有)和类属性(在共享)
使用__slots__
由于'score'没有被放到__slots__中,所以不能绑定score属性,试图绑定score将得到AttributeError的错误。
使用__slots__要注意,__slots__定义的属性仅对当前类实例起作用,对继承的子类是不起作用的:
>>> class GraduateStudent(Student):
>>> g = GraduateStudent()
>>> g.score = 9999
除非在子类中也定义__slots__,这样,子类实例允许定义的属性就是自身的__slots__加上父类的__slots__。
多重继承
一个子类就可以同时获得多个父类的所有功能
MixIn 给一个类增加多个功能
错误解决
找到错误位置 分析错误信息
使用try...except捕获错误可以跨越多层调用,函数main()调用bar(),bar()调用foo(),结果foo()出错了,只要main()捕获到就可以。
Q:
def foo(s):
return 10 / int(s)
def bar(s):
return foo(s) * 2
def main():
try:
bar('0')
except Exception as e:
print('Error:', e)
finally:
print('finally...')
出错的时候,一定要分析错误的调用栈信息,才能定位错误的位置。
错误是class,捕获一个错误就是捕获到该class的一个实例错误并不是凭空产生的,而是有意创建并抛出的。Python的内置函数会抛出很多类型的错误,我们自己编写的函数也可以抛出错误。
另一种类型
raise语句如果不带参数,就会把当前错误原样抛出。
调试
Assert
Logging(最方便)
pdb