Python–cookbook–7.函数

Python–cookbook–7.函数

导入对应模块

from functools import partial
from queue import Queue
from functools import wraps

可接受任意数量参数的函数

# 接受任意数量的位置参数,使用*
def avg(first, *rest):  # A tuple
    return (first + sum(rest)) / (1 + len(rest))
# print(avg(1, 2, 3, 4, 5))
# 接受任意数量的关键字参数,用**
def get_item(**attr):
    for k, v in attr.items():  # A dict
        print(k, v)
# get_item(a=1, b=2)

只接受关键字参数的函数

def mini(*values, clip=None):
    m = min(values)
    if clip is not None:
        m = clip if clip > m else m
    return m
print(mini(1, 5, 2, -5, 10))
print(mini(1, 5, 2, -5, 10, clip=0))  # 指定关键字

给函数参数增加元信息

def add(x:int, y:int) -> int:
    return x + y
print(add.__annotations__)  # 函数注解

返回多个值的函数(直接return)

def myfun():
    return 1, 2, 3  # 实际上是返回元组
a, b, c= myfun()

定义有默认参数的函数

def spam(a, b=42, c=None):  # 可修改容器使用None
    if c is None:
        c = []
    print(a, b, c)
spam(1, 25, [])
x = [1]
spam(1, 25, x)

测试某个参数是不是有传递进来

_no_value = object()
def spam2(a, b=_no_value):
    if b is _no_value:
        print('No b value supplied')
# spam2(1)
# spam2(2, None)

匿名函数捕获变量值

xx = 10
fun1 = lambda y: xx + y
xx = 20
fun2 = lambda y: xx + y
print(fun1(10), fun2(10))  # 30 30 xx是自由变量
funcs = [lambda x: x+n for n in range(5)]
for i in funcs:
    print(i(0), end=' ')
print()
# 定义时就捕获值
xx = 10
fun3 = lambda y, xx=xx: xx + y
xx = 20
fun4 = lambda y, xx=xx: xx + y
print(fun3(10), fun4(10))  # 20 30
# funcs = [lambda x, n=n: x+n for n in range(5)]

减少可调用对象的参数个数

# functools.partial()
def spam(a, b, c, d):
    return a, b, c, d
s1 = partial(spam, 10)  # a = 1
s2 = partial(spam, d=42)  # d = 42
s3 = partial(spam, 1, 2, d=42)  # a = 1, b = 2, d = 42
print(s1(2, 3, 4))

将单方法的类转换为函数

# 大多数情况下,可以使用闭包来将单个方法的类转换成函数。
# opener()函数记住了template参数的值(记住了变量)
# def urltemplate(template):
#     def opener(**kwargs):
#         return urlopen(template.format_map(kwargs))
#     return opener

带额外状态信息的回调函数

def apply_async(func, args, *, callback):
    result = func(*args)
    callback(result)
def print_result(result):
    print('Got:', result)
def add(x, y):
    return x + y
apply_async(add, (2, 3), callback=print_result)
apply_async(add, ('hello', 'world'), callback=print_result)

class ResultHandler:  # 让回调函数访问外部信息
    def __init__(self):
        self.sequence = 0  # 外部状态
    def handler(self, result):
        self.sequence += 1
        print('[{}] Got: {}'.format(self.sequence, result))
r = ResultHandler()
apply_async(add, (2, 3), callback=r.handler)
apply_async(add, ('hello', 'world'), callback=r.handler)

作为类的替代,使用闭包

def make_handler():
    sequence = 0
    def handler(result):
        nonlocal sequence
        sequence += 1
        print(f'{{{sequence}}} Got: {result}')
    return handler
handler = make_handler()
apply_async(add, (2, 3), callback=handler)
apply_async(add, ('hello', 'world'), callback=handler)

使用协程

def make_handler2():
    sequence = 0
    while True:
        result = yield
        sequence += 1
        print('[{}] Got: {}'.format(sequence, result))
handler = make_handler2()
next(handler)
apply_async(add, (2, 3), callback=handler.send)
apply_async(add, ('hello', 'world'), callback=handler.send)

内联回调函数

# from queue import Queue
# from functools import wraps
#
# def apply_async(func, args, *, callback):
# # Compute the result
#     result = func(*args)
#     callback(result)
# def add(x, y):
#     return x + y
# class Async:
#     def __init__(self, func, args):
#         self.func = func
#         self.args = args
#
# def inlined_async(func):
#     @wraps(func)
#     def wrapper(*args):
#         f = func(*args)
#         result_queue = Queue()
#         result_queue.put(None)
#         while True:
#             result = result_queue.get()
#             try:
#                 a = f.send(result)
#                 apply_async(a.func, a.args, callback=result_queue.put)
#             except StopIteration:
#                 break
#     return wrapper
# @inlined_async
# def test():
#     r = yield Async(add, (2, 3))
#     print(r)
#     r = yield Async(add, ('hello', 'world'))
#     print(r)
#     for n in range(10):
#         r = yield Async(add, (n, n))
#         print(r)
#     print('Goodbye')
# test()

访问闭包中定义的变量

def sample():
    n = 0
    def func():
        print('n=', n)
    def get_n():
        return n
    def set_n(value):
        nonlocal n
        n = value
    func.get_n = get_n
    func.set_n = set_n
    return func
f = sample()
f()
f.set_n(10)
f()
print(f.get_n())
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

柴寺仓

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值