math.sqrt() 返回的是浮点数
在python的shell下,如果要定义一个函数,需要使用ctrl+D或者Ctrl+Z来退出函数的定义,另外要手动缩进,否则会出错。
当利用readline()读到一个文件尾时,没有读到内容时会返回一个EOF。
而EOF如果被raw_input()之类的函数接收,则会引发一个EOFError错误。
map()是 Python 内置的高阶函数,它接收一个函数 f 和一个 list,并通过把函数 f 依次作用在 list 的每个元素上,得到一个新的 list 并返回。
map(f,x)
给定任意一个字符串,返回开头为大写其余为小写的格式
可使用str.title() str.capitalize() str[0].upper+str[1:].lower() 这么几种方法
reduce()函数也是Python内置的一个高阶函数。reduce()函数接收的参数和 map()类似,一个函数 f,一个list,但行为和 map()不同,reduce()传入的函数 f 必须接收两个参数,reduce()对list的每个元素反复调用函数f,并返回最终结果值。reduce()还可以接收第3个可选参数,作为计算的初始值。
reduce(f, [1, 3, 5, 7, 9], 100)
filter()函数是 Python 内置的另一个有用的高阶函数,filter()函数接收一个函数 f 和一个list,这个函数 f 的作用是对每个元素进行判断,返回 True或 False,filter()根据判断结果自动过滤掉不符合条件的元素,返回由符合条件元素组成的新list。True的情况才保留。None和false项会自动滤除。
x%2==0 偶数与否 x%2==1 奇数与否
s.strip(rm) 删除 s 字符串中开头、结尾处的 rm 序列的字符。
当rm为空时,默认删除空白符(包括‘\n‘, ‘\r‘, ‘\t‘, ‘ ‘)
Python内置的 sorted()函数可对list进行排序(默认是升序,数字字符串皆可),但 sorted()也是一个高阶函数,它可以接收一个比较函数来实现自定义排序,比较函数的定义是,传入两个待比较的元素 x, y,如果 x 应该排在 y 的前面,返回 -1,如果 x 应该排在 y 的后面,返回 1。如果 x 和 y 相等,返回 0。
sorted([36, 5, 12, 9, 21], reversed_cmp)
Python的函数不但可以返回int、str、list、dict等数据类型,还可以返回函数。在函数f内部可定义一个函数g。由于函数g也是一个对象,函数名g就是指向函数g的变量,所以,最外层函数f可以返回变量g,也就是函数g本身。
返回函数可以把一些计算延迟执行。由于可以返回函数,我们在后续代码里就可以决定到底要不要调用该函数。
def calc_prod(lst):
def a():
return reduce(lambda x,y:x*y, lst)
return a
def calc_prod(lst):
return lambda: reduce(lambda x, y : x * y, lst) //最短的结果
def calc_sum(lst):
def lazy_sum():
return sum(lst)
return lazy_sum
像这种内层函数引用了外层函数的变量(参数也算变量),然后返回内层函数的情况,称为闭包(Closure)。
闭包的特点是返回的函数还引用了外层函数的局部变量,所以,要正确使用闭包,就要确保引用的局部变量在函数返回后不能变。
返回多个函数
def count():
fs = []
for i in range(1, 4):
def f():
return i*i
fs.append(f)
return fs
f1, f2, f3 = count() 调用f1()、f2()、f()时,结果全是9,使用闭包时要注意避免这种情况。
def count():
fs = []
for i in range(1, 4):
def f(x=i): //默认量
return x*x
fs.append(f)
return fs
def count():
fs = []
for i in range(1, 4):
fs.append(lambda i=i : i*i)
return fs //返回匿名函数
关键字lambda 表示匿名函数,冒号前面的x表示函数参数。
匿名函数有个限制,就是只能有一个表达式,写return,返回值就是该表达式的结果,也即一个函数变量。
myabs = lambda x: -x if x < 0 else x //注意后面的语句
装饰器
采用的是高阶函数能接受函数并返回函数的特点。
def new_fn(f): //装饰器函数
def fn(x):
print “message”
return f(x)
return fn
Python内置的@语法就是为了简化装饰器的调用
可极大简化代码,避免编写重复性代码
打印日志 @log 检测性能@performance 数据库事务@transaction URL路由 @post(‘/register’)
def log(f): //装饰器函数
def fn(x):
print “Message” //添加想要的新功能
return f(x) //执行旧功能
return fn //把函数f装饰一下,让其变为一个含有说明的函数
@log //装饰函数
def f(x):
return x*2 //装饰器作用于下面定义的函数,f变成了装饰后的函数
@log 要先定义,然后才能用其来装饰其他新定义的函数
要让@log自适应任何参数定义的函数,可以利用Python的 *args 和 **kw,保证任意个数的参数总是能正常调用。
def log(f):
def fn(*args, **kw):
print ‘Message‘
return f(*args, **kw)
return fn
time 模块
start=time.time() //获取当前时间,以秒为单位
编写无参数decorator
import time
def performance(f):
def fn(*args,**kw):
start=time.time()
temp=f(*args,**kw)
end=time.time()
print ‘call %s() in %fs‘ % (f.__name__, (end - start))
return temp
return fn
@performance
def factorial(n):
return reduce(lambda x,y: x*y, range(1, n+1))
print factorial(10)
有参数的decorator
import time
def performance(unit):
def performance_l(f):
def fn(*args, **kw):
start = time.time()
temp= f(*args, **kw)
end= time.time()
print ‘call %s() in %s%s‘ % (f.__name__, (end-start), unit)
return temp
return fn
return performance_l
@performance(‘ms‘)
def factorial(n):
return reduce(lambda x,y: x*y, range(1, n+1))
print factorial(10)
完善decorator
@decorator可以动态实现函数功能的增加,但是,经过@decorator“改造”后的函数,和原函数相比,其一些原函数的属性比如__doc__、__name__等都会消失。因为其本质就是函数替换。
Python内置的functools可以用来自动化完成这个“复制”的任务
import functools
def log(f):
@functools.wraps(f)
def wrapper(*args, **kw):
print ‘call...‘
return f(*args, **kw)
return wrapper
@functools.wraps(f)应该放在最内层开头。 也即是 对最内层函数进行下装饰
如果不进行此项,最后装饰器返回的函数信息是最内层函数定义的信息。
functools.partial可以把一个参数多的函数变成一个参数少的新函数,少的参数需要在创建时指定默认值,这样,新函数调用的难度就降低了。即可重新定义函数的默认参数值。并返回一个新函数。
int2 = functools.partial(int, base=2)
模块和包
将所有代码放入一个py文件中,难以维护。
分拆放入多个py文件中。
好处:同一个名字的变量互不影响。
模块的名称就是py文件的文件名。
模块多了的话,也容易重名。把同名的模块放入不同的包。
import p1.util
print p1.util.f(2,10) //调用
在文件系统中,包就是文件夹,模块就是py文件。
包可以有多级。如何区分包和普通目录? 包下面必须有个__init__.py文件,每一层都要有,即使是空文件,这样python就会把这个目录当成一个包来处理。
import math //引入名称空间而已,调用还需加模块名
math.pow(2,0.5) math.pi
form math import pow,sin,log //引入特定函数
form math import * //会有重名冲突的风险
from math import log
from logging import log as logger //通过起别名来避免冲突
如果导入的模块不存在,Python解释器会报ImportError错误。
如果要提高Python代码的运行速度,最简单的方法是把某些关键函数用C语言重写,如此可大大提高执行速度。
如StringIO模块是纯Python代码编写的,而cStringIO模块部分函数是C写的。
常利用ImportError来进行动态导入
try:
from cStringIO import StringIO
except ImportError:
from StringIO import StringIO
利用import ... as ...,还可以动态导入不同名称的模块。
标准库的文件组织?