# [Python] 函数与函数编程

## 1. 函数

```def add(x, y):
return x + y```

```def split(line, delimiter=','):
statements```

```def fprintf(file, fmt, *args):
file.write(fmt % args)
fprintf(out, "%d %s %f", 42, "hello world", 3.45)```

```def printf(fmt, *args):
fprintf(sys.stdout, fmt, *args)```

```def foo(w, x, y, z):
statements
foo(x=3, y=22, w='hello', z=[1, 2])```

`foo('hello', 3, z=[1, 2], y=22)`

```def make_table(data, **params):
fgcolor = params.pop("fgcolor", "black")
bgcolor = params.pop("bgcolor", "white")
width = params.pop("width", None)
if params:
raise TypeError("Unsupported configuration options %s" % list(params))
make_table(items, fgcolor="black", bgcolor="white", border=1, borderstyle="grooved", cellpoadding=10, width=400)```

```def spam(*args, **kwargs):
statements```

## 2. 参数传递与返回值

```a = [1, 2, 3, 4, 5]
def square(items):
for i, x in enumerate(items):
items[i] = x * x
square(a) # a = [1, 4, 9, 16, 25]```

return语句从函数返回一个值。如果没有指定任何值或者省略return语句，就会返回None对象。如果返回值有多个，可以把它们放在一个元组中，例如：

```def factor(a):
d = 2
while (d <= (a / 2)):
if ((a / d) * d == a):
return ((a / d), d)
d = d + 1
return (a, 1)```

## 3. 作用域规则

```a = 42
def foo():
a = 13
foo() # a仍然是42```

```a = 42
def foo():
global a
a  = 13
foo() # a的值已变13```

Python支持嵌套的函数定义，例如：

```def countdown(start):
n = start
def display():
print('T-minus %d' % n)
while n > 0:
display()
n -= 1```

```def countdown(start):
n = start
def display():
print('T-minus %d' % n)
def decrement():
nonlocal n
n -= 1
while n > 0:
display()
decrement()```

nonlocal声明不会把名称绑定到任意函数中定义的局部变量，而是搜索当前调用栈中的下一层函数定义，即动态作用域。例如：

```i = 0
def foo():
i = i + 1 # UnboundLocalError异常```

## 4. 函数对象与闭包

```def callf(func):
return func()```

```# foo.py
x = 42
def callf(func):
return func()

# main.py
import foo
x = 37
def helloworld():
reutrn "x is %d" % x
foo.callf(helloworld) # x is 37```

```def page(url):
def get():
return get
python = page("http://www.python.org")
jython = page("http://www.jython.org")
pydata = python() # 获取http://www.python.org
jydata = jython() # 获取http://www.jython.org```

## 5. 装饰器

```@trace
def square(x):
return x * x```

```def square(x):
return x * x
square = trace(square)```

```enable_tracing =  True
if enable_tracing:
debug_log = open("debug.log", "w")

def trace(func):
if enable_tracing:
def callf(*args, **kwargs):
debug_log.write("Calling %s: %s, %s\n" % (func.__name__, args, kwargs))
r = func(*args, **kwargs)
debug_log.write("%s returned %s\n" % (func.__name__, r))
return r
return callf
else:
return func```

```@foo
@bar
@spam
def grok(x):
pass\
grok = foo(bar(spam(grok)))```

```@eventhandler('BUTTON')
def handle_button(msg):
...
@eventhandler('RESET')
def handle_reset(msg):
...```

```def handle_button(msg):
...
temp = eventhandler('BUTTON')
handle_button = temp(handle_button)```

## 6. 生成器与yield

```def countdown(n):
while n > 0:
yield n
n -=1
return```

```c = countdown(10)
c.__next__()```

```for n in countdown(10):
statements
a = sum(countdown(10))```

```c = countdown(10)
c.__next__()
c.close()
c.__next__() # 抛出异常```

```def countdown(n):
try:
while n > 0:
yield n
n -= 1
except GeneratorExit:
print("Only made it to %d" % n)```

## 7. 协程与yield表达式

```def receiver():
while True:
n = (yield)
print("Got %s" % n)```

```r = receiver()
r.__next__()
r.send(1)
r.send(2)```

```def coroutine(func):
def start(*args, **kwargs):
g = func(*args, **kwargs)
g.next()
return g
return start

@coroutine
while True:
n = (yield)
print("Got %s" % n)

r.send("Hello World")```

```r.close()
r.send() # 抛出异常```

## 8. 列表包含

```nums = [1, 2, 3, 4, 5]
squares = [n * n for n in nums]```

```[expression for item1 in iterable1 if condition1
for item2 in iterable2 if condition2
...
for itemN in iterableN if conditionN]```

```a = [-3, 5, 2, -10, 7, 8]
b = 'abc'
c = [2 * s for s in a] # c = [-6, 10, 4, -20, 14, 16]
d = [s for s in a if s >= 0] # d = [5, 2, 7, 8]
e= [(x, y) for x in a
for y in b
if x > 0]
# e = [(5, 'a'), (5, 'b'), (5, 'c'),
(2, 'a'), (2, 'b'), (2, 'c'),
(7, 'a'), (7, 'b'), (7, 'c'),
(8, 'a'), (8, 'b'), (8, 'c')]
f = [(1, 2), (3, 4), (5, 6)]
g  = [math.sqrt(x * x + y * y) for x, y in f] # g = [2.23606797749979, 5.0, 7.810249675906654]```

## 9. 生成器表达式

```(expression for item1 in iterable1 if condition1
for item2 in iterable2 if condition2
...
for itemN in iterableN if conditionN)```

```a  = [1, 2, 3, 4]
b = (10 * i for i in a)
print(b.__next__())
print(b.__next__())```

```f = open("data.txt")
lines = (t.strip() for t in f)
comments = (t for t in lines if t[0] == '#')
print(c)```

`clist = list(comments)`

## 10. lambda运算符

`lambda args: expression`

args是以逗号分隔的参数列表，而expression是用到这些参数的表达式，例如：

```a = lambda x, y: x + y
r = a(2, 3)```

## 11. 文档字符串

```def factorial(n):
"""Computes n factorial. For examples:
>>> factorial(6)
120
"""
if n <= 1: return 1
else: return n* factorial(n-1)```

```def wrap(func):
call(*args, **kwargs):
return func(*args, **kwargs)
return call
@wrap
def factorial(n):
"""Computes n factorial."""```

```def wrap(func):
call(*args, **kwargs):
return func(*args, **kwargs)
call.__doc__ =  func.__doc__
call.__name__ = func.__name__
return call```

```from functools import wraps
def wrap(func):
@wrap(func)
call(*args, **kwargs):
return func(*args, **kwargs)
return call```

## 12. 函数属性

```def foo():
statements
foo.secure = 1
foo.private = 1```

## 13. eval()、exec()和compile()函数

eval(str [, globals [, locals]])函数执行一个表达式字符串并返回结果，例如：

`a = eval('3 * math.sin(3.5 + x) + 7.2')`

```a = [3, 5, 10, 13]
exec("for i in a: print(i)")```

```globals = {'x': 7, 'y': 10, 'birds': ['Parrot', 'Swallow', 'Albatross']}
locals = {}
a = eval("3 * x + 4 * y", globals, locals)
exec("fro b in birds: print(b)", globals, locals)```

compile(str, filename, kind)函数将字符串编译为字节码，其中str是包含要编译代码的字符串，而filename是定义该字符串的文件，kind参数指定了要编译代码的类型。single表示一条语句，exec代表一组语句，而eval代表一个表达式。例如：

```s = "for i inrange(0, 10): print(i)"
c = compile(s, '', 'exec')
exec(c)
s2 = "3 * x + 4 * y"
c2 = compile(s2, '', 'eval')
result = eval(c2)```

0 条评论

• ### Python基础——4高阶函数

map()函数接收两个参数，一个是函数，一个是Iterable，map将传入的函数依次作用到序列的每个元素，并把结果作为新的Iterator返回。

• ### 学习笔记-小甲鱼Python3学习第十七

优秀的东西永远是经典的，经典的东西永远是简单的，不是说复杂不好，而是能够把复杂的东西简单化，堪称经典。

• ### openssl创建CA、申请证书及其给web服务颁发证书

一、创建私有的CA 1）查看openssl的配置文件:/etc/pki/tls/openssl.cnf ? 2）创建所需的文件 touch /etc/pki...

• ### 斯诺登称NSA安全项目或误伤普通网络用户

美国国家安全局(NSA)前雇员爱德华·斯诺登(Edward Snowden)近期表示，美国政府正在推进一个名为“MonsterMind”的信息安...

• ### ASP.NET MVC5+EF6+EasyUI 后台管理系统（41）-组织架构

本节开始我们要实现工作流，此工作流可以和之前的所有章节脱离关系，也可以紧密合并。 我们当初设计的项目解决方案就是可伸缩可以拆离，可共享的项目解决方案。所以我们同...