使用装饰器的包装函数来更改函数的参数

时间:2017-12-11 01:35:29

标签: python python-3.x decorator python-decorators

我在装饰员周围缠头时遇到了一些麻烦。 我想在装饰器中使用包装器函数将更改应用于我的 request.Session()object。

这是我作为装饰者尝试时的功能:

import os
import requests
from requests.adapters import HTTPAdapter
from requests.packages.urllib3.util.retry import Retry

#want to make changes to my session object and return the  new object
# as a argument to my original function

def decorator_function(func):
        def wrapper(*args, **kwargs):
            session = requests.Session()
            retry = Retry(connect=2, backoff_factor=0.2)
            adapter = HTTPAdapter(max_retries=retry)
            session.mount('http://', adapter)
            session.mount('https://', adapter)

            return func(*args, **kwargs)
        return wrapper

为了能够将会话参数提供给我的包装函数的参数,我在我的原始函数中将session作为关键字参数:

def download_image(SAVE_DIR, image_links, session = None):

        if not session:
                session = requests.Session()

        for num,link in enumerate(image_links):

            try:
                r = s.get(link)

            except (requests.exceptions.RequestException, UnicodeError) as e:
                     print(e)

            with open(os.path.join(
                        SAVE_DIR, 'image_{}.jpg'.format(num)),
                        'wb') as f:
                f.write(r.content)

正如您所见,session的默认值为None,但我试图使用装饰器创建一个特殊的会话对象并将其提供给函数,覆盖默认值None。

我使用** args和** kwargs作为包装函数的参数,因为如果我有 其他带有附加参数的函数,我仍然可以使用这个装饰器。

然而,似乎如果我使用* args,* kwargs,我无法对会话参数进行更改。

是否有一种优雅的方式来使用装饰器函数来更改会话对象,并且仍保留通用性以将其包装在除会话对象之外可能具有更多不同参数的其他函数中?

1 个答案:

答案 0 :(得分:0)

更改此行return func(*args, **kwargs)

return func(*args, session =session, **kwargs)

问题是你创建了会话而没有真正做任何事情。