【发布时间】:2019-07-22 15:49:09
【问题描述】:
发生了什么事?...
所以,这就是我的情况。我正在详细说明网络抓取,因此在此脚本的某个时刻,我决定使用装饰器来处理某些 URL。这个装饰器有一个参数(URL),它应该在 for 循环语句的帮助下动态变化,如示例脚本所示:
from functools import wraps
import logging
logging.basicConfig(level=logging.INFO)
def cycle(url):
def outer_wrapper(func):
state = 0
@wraps(func)
def inner_wrapper(**kwargs):
nonlocal state
state += 1
kwargs['url'] = url
if state == 1:
logging.info('Returning result at first execution on {} with: '
'state => {}, kwargs => {}'.format(func, state, kwargs))
return func(**kwargs)
else:
logging.info('Returning result at upcoming executions on {} with: '
'state => {}, kwargs => {}'.format(func, state, kwargs))
return func(**kwargs)
return inner_wrapper
return outer_wrapper
def print_url(url):
print('Returned from print_url function:', url)
links = ['an-url', 'another-url']
for link in links:
# Decorator
print_url = cycle(link)(print_url)
print_url()
但是,输出显示出意想不到的结果,至少对我来说是这样。
INFO:root:Returning result at first execution on <function print_url at 0x000002202FD68D08> with: state => 1, kwargs => {'url': 'an-url'}
Returned from print_url function: an-url
INFO:root:Returning result at first execution on <function print_url at 0x000002202FE196A8> with: state => 1, kwargs => {'url': 'another-url'}
INFO:root:Returning result at upcoming executions on <function print_url at 0x000002202FD68D08> with: state => 2, kwargs => {'url': 'an-url'}
Returned from print_url function: an-url
装饰器保留第一次调用print_url() 函数的地址和参数。
我已经阅读了很多关于垃圾收集、弱引用和标准库的functools 的文章,但我不知道如何“重新启动”这个装饰器,以便在迭代过程中接收一个新参数。
如果可能的话,有人知道如何解决这个问题吗?
【问题讨论】:
-
因为你正在重新装饰你已经装饰的函数。
标签: python python-3.x decorator