python - 使用 Python 装饰器对结果取模
问题描述
我正在学习 Python 中的装饰器,但在使用的装饰器上遇到了一些问题:
@curry
def modulo(mod,f):
if mod:
@fun.wraps(f)
def wrapper(*args, **kw):
result = f(*args, **kw)
return tuple(r % mod for r in result)
else:
return f
return wrapper
curry 装饰器是一个简单的柯里化,所以我可以在下面调用 mod 作为参数:
def _fib(p=1,q=-1,mod=None):
''' Fibonacci sequence '''
@modulo(mod)
def next_fib(pair):
x,y = pair
return y, p*x - q*y
yield from ( y for x,y in iterate(next_fib,(1,0)) )
它有效,看起来又漂亮又干净。但是,假设我想要另一个 [密切相关的] 卢卡斯序列生成器:
def _luc(p=1,q=-1,mod=None):
''' Lucas sequence '''
@modulo(mod)
def next_luc(pair):
x,y = pair
return y, p*x - q*y
yield from ( y for x,y in iterate(next_luc,(p-2,2)) )
如果我把它们放在一起,我会遇到某种冲突:
>>> F = _fib()
>>> print(take(10,F))
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
>>> L = _luc()
>>> print(take(10,L))
" ... TypeError: cannot unpack non-iterable function object"
单独调用它们按预期工作,并返回正确的模块化术语。
我的问题是双重的:这是一个命名空间冲突,它们都指的是模()吗?你会怎么做这样的事情?
辅助功能:
import itertools as it
import functools as fun
def curry(f):
argc = f.__code__.co_argcount
f_args = []
f_kwargs = {}
@fun.wraps(f)
def wrapper(*args, **kwargs):
nonlocal f_args, f_kwargs
f_args += args
f_kwargs.update(kwargs)
if len(f_args)+len(f_kwargs) == argc:
return f(*f_args, **f_kwargs)
else:
return wrapper
return wrapper
def iterate(f,x):
''' x, f(x), f(f(x)), f(f(f(x))), ... '''
return it.accumulate(it.repeat(x), lambda fx, _: f(fx))
def take(n,iterable):
return [x for x in it.islice(iterable,n)]
解决方案
我发现扩展原始模包装器可以解决问题!感谢Thomas_Breydo建议更改咖喱函数
def modulo(mod):
def wrapper(f):
@fun.wraps(f)
def deco(*args,**kwargs):
if mod:
return tuple(n%mod for n in f(*args,**kwargs) )
else:
return f(*args,**kwargs)
return deco
return wrapper
这解决了我的问题。
推荐阅读
- python - Python给出ValueError:list.remove(x):从列表中删除元组时x不在列表中
- python - TFLearn 回归损失函数未初始化
- android - 调用改造 2 时避免内存泄漏
- c# - ASP.NET Razor Pages 提交按钮什么都不做
- dynamics-ax-2012 - 如何从 Dynamics AX(财务和运营)获取所有 DataEntity 数据?
- php - PHP 谷歌加域 api 删除帖子和评论
- python - pymongo:[Errno 10013] 尝试以访问权限禁止的方式访问套接字
- powerbi - 如何将筛选器添加到切片器以显示基于使用 Power BI 的选择计算的度量
- css - 如何在 Contact Form 7 中格式化不一致的电子邮件字体?
- c# - 创建继承的响应对象