【发布时间】:2019-04-22 12:23:34
【问题描述】:
我已经看到(很多)教程和带有和不带参数的装饰器的 sn-ps,包括那些我认为是规范答案的两个:Decorators with arguments、python decorator arguments with @ syntax,但我没有看看为什么我的代码会出错。
以下代码位于文件decorators.py:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Description: decorators
"""
import functools
def repeat(nbrTimes=2):
'''
Define parametrized decorator with arguments
Default nbr of repeats is 2
'''
def real_repeat(func):
"""
Repeats execution 'nbrTimes' times
"""
@functools.wraps(func)
def wrapper_repeat(*args, **kwargs):
while nbrTimes != 0:
nbrTimes -= 1
return func(*args, **kwargs)
return wrapper_repeat
return real_repeat
我从语法检查器得到的第一个警告是 nbrTimes 是一个“未使用的参数”。
我在 python3 交互式控制台中测试了上述内容:
>>> from decorators import repeat
>>> @repeat(nbrTimes=3)
>>> def greetings():
>>> print("Howdy")
>>>
>>> greetings()
Traceback (most recent call last):
File "<stdin>", line 1 in <module>
File path/to/decorators.py, line xx in wrapper_repeat
'''
UnboundLocalError: local variable 'nbrTimes' referenced before assignment.
我只是不明白我在哪里搞砸了。在其他示例中,传递的参数(此处为nbrTimes)直到稍后在内部函数中才“使用”,因此“未使用的参数”警告和执行时的错误让我有点兴奋。对 Python 来说还是比较新的。非常感谢您的帮助。
编辑:(回应@recnac 的duplicate 标志)
根本不清楚您声称的副本中的 OP 想要实现什么。我只能推测他/她打算从全局范围访问装饰器包装器中定义的计数器,但未能将其声明为nonlocal。事实上,我们甚至不知道 OP 处理的是 Python 2 还是 Python 3,尽管这在很大程度上无关紧要。我向您承认,错误消息非常相似,如果不相等,即使不一样。但是,我的意图不是从全局范围访问包装器内定义的计数器。我打算让这个柜台纯粹是本地的,并且做到了。我的编码错误完全在别处。事实证明,Kevin(如下)提供的出色讨论和解决方案具有本质上的性质,与仅在包装器定义块中添加 nonlocal <var> 完全不同(在 Python 3.x 的情况下)。我不会重复凯文的论点。它们是清晰的,可供所有人使用。
最后,我冒昧地说,错误消息可能是这里最不重要的,尽管它显然是我的错误代码的结果。为此我进行了修正,但这篇文章绝对不是对提议的“重复”的重新讨论。
【问题讨论】:
-
旁白:当代码风格一致时,代码更容易阅读。在其他 PEP 8 格式的代码中调用
nbrTimes会在视觉上不和谐。考虑将其重命名为nbr_times、number_of_times甚至只是times。 -
@Chris;对不起,我是新手。我什至不知道有这种约定。在写作时,我倾向于使用我在笔中找到的任何墨水。用于单挑的 Tx ...
-
不客气,Cbhihe。为了完整起见,这里是 PEP 8(Python 的官方风格指南)的链接:python.org/dev/peps/pep-0008。您不必必须遵循该指南,但大多数 Python 开发人员都会这样做。祝你好运!
标签: python python-3.x python-decorators default-parameters