evernote原文链接:https://app.yinxiang.com/shard/s7/sh/a02a1922-3a7c-4c5f-9cb2-503154600b02/c542bb3892f941ed
(有些图片不能显示,请点击 evernote 原文查看)
Python 函数与函数编程(1)
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
'''
Created on 2015年1月27日
@author : cuckoocs
'''
import foo
'''
笔记1:
调用函数时,函数参数只是引用传入对象的名称,函数可以返回多个值,其实是一个序列
参数定义中使用 *arg 表示着不定数量和位置的参数, **args 代表不定数量的 k=v 参数传递
笔记2:
每个函数就是一个作用域,要可以在函数中使用 global 指明为外部作用域的参数
eg:
global delta
delta = 80
笔记3:
函数支持嵌套定义,但是注意嵌套函数的作用域和嵌套函数内变量的作用域,需要在嵌套函数中使用外部函数的变量,可以使用引用传递给嵌套函数
笔记4:
函数是第一对象,能当做参数传递
笔记5:
函数可以接受一个函数作为参数传入,也可以返回一个函数
当函数当做数据处理时,函数将显示的携带与定义该函数的周围环境相关的信息
函数闭包就是把组成函数的语句和这些语句的执行环境一起打包,可以通过一个__globals__ 内置变量查看函数的环境
eg:helloworld.__globals__
笔记6:
使用嵌套函数的时候,闭包会捕捉内部函数执行所需的整个环境
笔记7:
如果需要在一系列函数调用中保持某个状态可以是用闭包,闭包的效率比使用类对象控制要高
eg:countdown 函数
笔记8:
装饰器也是一个函数,可以增强被包装函数的功能
是用'@'符号
eg:
'''
delta = 90
def tfun():
global delta
delta = 80
print delta
def content():
cont = 'content'
def foo():
cont = 'foo content'
print cont
foo()
print cont
x = 44
def helloworld():
return 'helll world %s' % x
def bar():
x = 90
def helloworld():
return 'bar hello world %s' % x
print foo.callf(helloworld)
def countdown(kv):
def next():
# python 3 中可以使用 nonlocal n
r = kv['n']
kv['n'] -= 1
return r
return next
if __name__ == '__main__':
# tfun()
# print delta
# content()
# print foo.callf(helloworld) #helll world 44
# print helloworld.__globals__
# bar() #bar hello world 90
#eg闭包
# kv = {'n':10}
# next = countdown(kv)
# while(True):
# v = next()
# print v
# if not v:
# break
#
# print kv
#eg闭包 end
pass
Python 函数与函数编程(2)
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
'''
Created on 2015年1月28日
@author : cuckoocs
'''
'''
笔记1:
列表推导式
列表推导式语法[pic-1]
[(x,y)for x in a for y in b]写法是合法的
[x,y for x in a for y in b]写法不合格
笔记2:
生成器表达式
生成器表达式语法与列表推导式一样,只是使用'()'而不是'[]',语法如[pic-2]
生成器表达式可以用 list 转换成列表
笔记3:
列表推导会生成一个包含结果的列表,生成器表达式只是生成一个生成器对象
笔记4:
lambda 运算符,使用 lambda语句可以创建表达式形式的匿名函数
lambda args: expression
lambda 的主要用途是指定短小的回调函数
笔记5:
递归不能用在协程和生成器函数中
函数可以添加任意属性,foo.private = 1,函数属性保存在函数的__dict__ 属性中
'''
if __name__ == '__main__':
#生成器生成
b = (x for x in range(4))
print b
print list(b)
#end-1
#lambda
f = lambda x,y:x+y
print f(1,2)
#lambda end
Python 函数与函数编程(3)
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
'''
Created on 2015年1月28日
@author : cuckoocs
'''
'''
函数装饰器,方法装饰函数一般需要返回一个函数,类装饰函数一般需要返回一个类对象
笔记1:
一般装饰器,通过参数传递实现装饰
#一般函数
def get_player_info():
print 'name:{}, age:{}'.format('cst', 22)
#通过参数传递函数
def check_player(func):
print 'check player'
func()
print 'check end'
if __name__ == '__main__':
check_player(get_player_info)
笔记2:
使用 python '@'语法糖,不使用函数内嵌包装
这样的写法
#通过参数传递函数
def check_player(func):
print 'check player'
func()
print 'check end'
#return func (1)
#一般函数
@check_player
def get_player_info():
print 'name:{}, age:{}'.format('cst', 22)
if __name__ == '__main__':
get_player_info()
如若不引用(1)处代码会报出这样的错误
check player
name:cst, age:22
check end
Traceback (most recent call last):
File "/Users/monstar-216/workspace/PythonReferenceManual/chapter6/decorators.py", line 53, in <module>
get_player_info()
TypeError: 'NoneType' object is not callable
引用(1)处后的代码会造成函数执行两次,结果:
check player
name:cst, age:22
check end
name:cst, age:22
笔记3:
使用语法糖和函数内嵌包装
def check_player(func):
def pkg():
print 'check player'
func()
print 'check end'
return pkg
#一般函数
@check_player
def get_player_info():
print 'name:{}, age:{}'.format('cst', 22)
if __name__ == '__main__':
get_player_info()
结果修正了通过2的重复执行:
check player
name:cst, age:22
check end
笔记4:
带参数的函数包装, 需要在内嵌函数中带参数,执行 func 的时候可以直接传入函数
def check_player(func):
def __pkg(name, age):
print 'check player'
rst = func(name, age)
print 'check end'
return rst
return __pkg
@check_player
def get_player_info(name, age):
print 'name:{}, age:{}'.format(name, age)
return {'name':name, 'age':age}
对不确定参数,也可以一起传递
def check_player(func):
def __pkg(name, age, *args, **kwargs):
print 'check player'
rst = func(name, age, *args, **kwargs)
print 'check end'
return rst
return __pkg
@check_player
def get_player_info(name, age, *args, **kwargs):
print 'name:{}, age:{}'.format(name, age)
if args:
print 'args is %s' % args
if kwargs:
print 'kwargs is %s' % kwargs
return {'name':name, 'age':age}
笔记5:
如果装饰器需要带参数,则需要再内嵌一层函数封装参数
def check_player(*args, **kwargs):
def _pkg(func):
if args:
print 'args is %s' % args
if kwargs:
print 'kwargs is %s' % kwargs
def __pkg(name, age, *args, **kwargs):
print 'check player'
rst = func(name, age, *args, **kwargs)
print 'check end'
return rst
return __pkg
return _pkg
@check_player('ARG', k='key')
def get_player_info(name, age, *args, **kwargs):
print 'name:{}, age:{}'.format(name, age)
if args:
print 'args is %s' % args
if kwargs:
print 'kwargs is %s' % kwargs
return {'name':name, 'age':age}
'''
#通过参数传递函数
def check_player(*args, **kwargs):
def _pkg(func):
if args:
print 'args is %s' % args
if kwargs:
print 'kwargs is %s' % kwargs
def __pkg(name, age, *args, **kwargs):
print 'check player'
rst = func(name, age, *args, **kwargs)
print 'check end'
return rst
return __pkg
return _pkg
@check_player('ARG', k='key')
def get_player_info(name, age, *args, **kwargs):
print 'name:{}, age:{}'.format(name, age)
if args:
print 'args is %s' % args
if kwargs:
print 'kwargs is %s' % kwargs
return {'name':name, 'age':age}
if __name__ == '__main__':
print 'the end rst: %s' % get_player_info('cccc', 33, sex=0)
Python 函数与函数编程(4)
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
'''
Created on 2015年1月28日
@author: cuckoocs
'''
'''
yield 使用
yield 可以用作生成器,也可以用作协成
笔记1:
在用作生成器上,yield 具体功能相当于 return, 但是不会剪断函数运行
生成器使用 next() 来获取下一个值,使用 close() 来关闭生成器
def countdown(n):
while(n):
yield n
n -= 1
#code2
def countdown(n):
def csum(n):
return n * n
while(n):
yield csum(n)
n -= 1
if __name__ == '__main__':
c = countdown(10)
c.next()
for x in c:
print x
笔记2:
在用作协程上, yield 相当于表达式,赋值表达式
协程首先要使用 next 激活,然后使用 send 赋值,使用 close 关闭协程
def receiver():
while True:
x = yield
print 'get %s' % x
if __name__ == '__main__':
c = countdown(10)
r = receiver()
r.next()
c.next()
for x in c:
print x
r.send(x)
'''
def countdown(n):
def csum(n):
return n * n
while(n):
yield csum(n)
n -= 1
def receiver():
while True:
x = yield
print 'get %s' % x
if __name__ == '__main__':
c = countdown(10)
r = receiver()
r.next()
c.next()
for x in c:
print x
r.send(x)
foo.py
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
'''
Created on 2015年1月28日
@author: cuckoocs
'''
'''
作为其他模块的引用
'''
x = 76
def callf(func):
print 'foo x is %s' % x
return func()