标签: functools

如何使多个@wraps更小?

我对 python 还不够了解,无法自己解决这个问题,所以这就是我想在这里尝试的原因。有没有办法让这些几乎相同的@wraps函数占用更少的空间?我总共有 5 个这样的东西,100 行 5 次同样的东西听起来很浪费。我最初在某个网站上找到过这个,但现在似乎找不到了。

功能:

def a_required(func):
    @wraps(func)
    def decorated_view(*args, **kwargs):
        if request.method in EXEMPT_METHODS:
            return func(*args, **kwargs)
        elif current_app.config.get('LOGIN_DISABLED'):
            return func(*args, **kwargs)
        elif not current_user.is_authenticated or not current_user["Keys"]["A"]:
            return current_app.login_manager.unauthorized()
        return func(*args, **kwargs)
    return decorated_view

def b_required(func):
    @wraps(func)
    def decorated_view(*args, **kwargs):
        if request.method in EXEMPT_METHODS:
            return func(*args, **kwargs)
        elif current_app.config.get('LOGIN_DISABLED'):
            return func(*args, **kwargs)
        elif not current_user.is_authenticated or not current_user["Keys"]["B"]:
            return current_app.login_manager.unauthorized()
        return func(*args, **kwargs)
    return decorated_view
Run Code Online (Sandbox Code Playgroud)

这是一个 Flask 网站,其页面只有拥有正确权限的用户才能访问。

python functools

1
推荐指数
1
解决办法
79
查看次数

使用 lru_cache 和 __hash__ 缓存对象实例

我不明白如何functools.lru_cache处理对象实例。我假设该类必须提供一种__hash__方法。因此任何具有相同哈希值的实例都应该hit缓存。

这是我的测试:

from functools import lru_cache

class Query:    
    def __init__(self, id: str):
        self.id = id

    def __hash__(self):
        return hash(self.id)

@lru_cache()
def fetch_item(item):
    return 'data'

o1 = Query(33)
o2 = Query(33)
o3 = 33

assert hash(o1) == hash(o2) == hash(o3)

fetch_item(o1)  # <-- expecting miss
fetch_item(o1)  # <-- expecting hit
fetch_item(o2)  # <-- expecting hit BUT get a miss !
fetch_item(o3)  # <-- expecting hit BUT get a miss !
fetch_item(o3)  # <-- expecting hit …
Run Code Online (Sandbox Code Playgroud)

python caching functools

1
推荐指数
1
解决办法
4353
查看次数

Python 装饰器 - &lt;Classname&gt; 对象没有属性 '__name__'

我有一个像下面这样的龙卷风方法,我试图装饰方法来缓存东西。我有以下设置

def request_cacher(x):
    def wrapper(funca):
        @functools.wraps(funca)
        @asynchronous
        @coroutine
        def wrapped_f(self, *args, **kwargs):
            pass

        return wrapped_f
    return wrapper

class PhotoListHandler(BaseHandler):
    @request_cacher
    @auth_required
    @asynchronous
    @coroutine
    def get(self):
        pass
Run Code Online (Sandbox Code Playgroud)

我收到错误,有AttributeError: 'PhotoListHandler' object has no attribute '__name__' 什么想法吗?

python tornado decorator functools python-decorators

0
推荐指数
1
解决办法
2092
查看次数

使用 lru_cache 装饰器测试功能

我正在尝试测试一个被记忆的方法lru_cache(因为它是一个昂贵的数据库调用)。和pytest-mock.

代码的简化版本是:

class User:

    def __init__(self, file):
        # load a file

    @lru_cache
    def get(self, user_id):
        # do expensive call
Run Code Online (Sandbox Code Playgroud)

然后我正在测试:

class TestUser:

    def test_get_is_called(self, mocker):
        data = mocker.ANY
        user = User(data)
        repository.get(user_id)
        open_mock = mocker.patch('builtins.open', mocker.mock_open())
        open_mock.assert_called_with('/foo')

Run Code Online (Sandbox Code Playgroud)

但我收到以下错误:

TypeError: unhashable type: '_ANY'
Run Code Online (Sandbox Code Playgroud)

发生这种情况是因为functools.lru_cache需要存储的密钥是​​可散列的,即有一个方法__hash____cmp__实现。

我怎样才能在嘲笑者中嘲笑这些方法以使其工作?

我试过了

user.__hash__.return_value = 'foo'
Run Code Online (Sandbox Code Playgroud)

没有运气。

python mocking pytest functools

0
推荐指数
2
解决办法
1881
查看次数

是否可以使用参数自动生成函数?

我有一个方法可以根据形状的名称和一些参数绘制一条线或任何形状的补丁,它工作正常:

def draw_a_shape(ax, is_patch_not_line, shapename, **kwargs):
  ...
Run Code Online (Sandbox Code Playgroud)

现在我需要有 30 多个函数,比如draw_a_square_patchdraw_an_ellipse_outline等等。我可以用一种简单的方式实现它们,如下所示,但这有点痛苦:

def draw_a_square_patch(ax, **kwargs):
  draw_a_shape(ax=ax, is_patch_not_line=True, shapename='a_square', **kwargs)
def draw_a_square_outline(ax, **kwargs):
  draw_a_shape(ax=ax, is_patch_not_line=False, shapename='a_square', **kwargs)
def draw_an_ellipse_patch(ax, **kwargs):
  draw_a_shape(ax=ax, is_patch_not_line=True, shapename='an_ellipse', **kwargs)
def draw_an_ellipse_outline(ax, **kwargs):
  draw_a_shape(ax=ax, is_patch_not_line=False, shapename='an_ellipse', **kwargs)
.........
Run Code Online (Sandbox Code Playgroud)

我想知道是否有办法使用循环来做到这一点,也许像setattr?我在下面添加了一个无效的代码,只是为了解释我的意思:

for shapename in ['a_circle', 'a_square', ...]:
  for is_patch_not_line in [False, True]:
    new_func_name = "draw_" + shapename + "_"
    if is_patch_not_line:
      new_func_name += "patch"
    else:
      new_func_name += "outline"
    global.setattr(new_func_name, "ax, **kwargs", ...) 
Run Code Online (Sandbox Code Playgroud)

python functools

0
推荐指数
1
解决办法
59
查看次数

导入错误:无法从“functools”导入名称“缓存”

我设法找到的所有解决方案都只在lru_cache. 但就我而言dir(functools),这表明这lru_cache确实存在于functoolswhilecache中!我该如何解决这个问题?

python functools

0
推荐指数
1
解决办法
2492
查看次数