相关疑难解决方法(0)

假设有许多重复项,使用 numpy 向量化“纯”函数

我想将“黑匣子”Python 函数f应用于大数组arr。额外的假设是:

  • 函数f是“纯的”,例如是确定性的,没有副作用。
  • 数组arr具有少量唯一元素。

我可以使用一个装饰器来实现这一点,该装饰器f为每个唯一元素计算arr如下:

import numpy as np
from time import sleep
from functools import wraps


N = 1000
np.random.seed(0)
arr = np.random.randint(0, 10, size=(N, 2))


def vectorize_pure(f):
    @wraps(f)
    def f_vec(arr):
        uniques, ix = np.unique(arr, return_inverse=True)
        f_range = np.array([f(x) for x in uniques])
        return f_range[ix].reshape(arr.shape)
    return f_vec


@np.vectorize
def usual_vectorize(x):
    sleep(0.001)
    return x


@vectorize_pure
def pure_vectorize(x):
    sleep(0.001)
    return x

# In [47]: %timeit usual_vectorize(arr)                                
# 1.33 s …
Run Code Online (Sandbox Code Playgroud)

python numpy unique vectorization pandas

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

使用 functools.wraps 装饰器尝试类的每个函数

我试图定义一个装饰器来执行一个类方法,首先尝试它,如果检测到错误,则提出它并提及失败的方法,以便用户可以看到哪个方法是错误的。

在这里,我展示了我的代码的MRE(最小的、可重现的示例)。

from functools import wraps

def trier(func):
    """Decorator for trying A-class methods"""
    @wraps(func)
    def inner_func(self, name, *args):
        
        try:
            func(self, *args)
        
        except:
            print(f"An error apeared while {name}")
    
    return inner_func
    
class A:
    def __init__(self):
        self._animals = 2
        self._humans = 5
    
    @trier('getting animals')
    def animals(self, num):
        return self._animals + num
    
    @trier('getting humans')
    def humans(self):
        return self._humans

A().animals
Run Code Online (Sandbox Code Playgroud)

出现许多错误,例如:

类型错误:inner_func() 缺少 1 个必需的位置参数:“名称”

或者误解 self class 与 self function 。

python decorator wrapper functools

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

装饰函数有没有办法引用装饰器创建的对象?

我想知道装饰函数是否有办法引用装饰器包装器创建的对象.当我想要使用装饰器时,我的问题出现了:

  1. 制作一个用子图创建图形的包装器
  2. 在包装器内执行装饰函数,这将添加一些图
  3. 最后将数字保存在包装器中

但是,修饰函数需要引用包装器创建的图形.装饰函数如何引用该对象?我们是否必须诉诸全局变量?

这是一个简短的例子,我在装饰函数中引用了一个在包装器中创建的变量(但是我没有设法在没有使用全局变量的情况下执行此操作):

def my_decorator(func):
    def my_decorator_wrapper(*args, **kwargs):
        global x
        x = 0
        print("x in wrapper:", x)
        return func(*args, **kwargs)
    return my_decorator_wrapper

@my_decorator
def decorated_func():
    global x
    x += 1
    print("x in decorated_func:", x)

decorated_func()
# prints:
# x in wrapper: 0
# x in decorated_func: 1
Run Code Online (Sandbox Code Playgroud)

我知道这很容易在课堂上完成,但我出于好奇而问这个问题.

python python-decorators

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

我如何制作一个虚拟的@jit 装饰器?

我希望 numba 是一个可选的依赖项,以便安装时速度很快,如果不安装则速度很慢。所以当没有安装 numba 时,我想@njit成为一个什么都不做的虚拟装饰者。

如果我遵循这些说明并使用:

def njit(func):
    return func
Run Code Online (Sandbox Code Playgroud)

然后当装饰器被调用时,@njit(cache=True, nogil=True)我收到以下错误:

TypeError: njit() got an unexpected keyword argument 'cache'

如果我尝试捕获参数并使用忽略它们

    def njit(func, *args, **kwargs):
        return func
Run Code Online (Sandbox Code Playgroud)

然后我得到:

missing 1 required positional argument: 'func'

我如何制作一个什么都不做并且忽略 kwargs 的虚拟装饰器?

python decorator python-decorators numba

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

将命令行参数传递给调用带有装饰器参数的装饰函数的函数

这个例子是人为的,但代表了现实生活中的情况:

  1. 我有一个接受命令行参数的 python 脚本。

  2. main()将解析参数,并将它们传递给中间函数(caller_func在代码示例中)

  3. 然后,中间函数将调用一个用fromfib()修饰的修饰函数(在示例中),并且缓存的 是从命令行接受并通过中间函数传递的参数。lru_cachefunctoolsmaxsize

我该怎么做呢?

import argparse
from functools import lru_cache

def main():
    # boilerplate for parsing command line arguments
    parser = argparse.ArgumentParser()
    parser.add_argument("--cache_size", default="10")
    parser.add_argument("--fibo_num", default="20")
    args = parser.parse_args()
    cache_size = int(args.cache_size)
    fibo_num = int(args.fibo_num)

    caller_func(cache_size, fibo_num)

#Intermediate function that is supposed to call decorated function
def caller_func(cache_size, fib_num): 
    print(fib(fib_num))

#function decorated by LRU cache
@lru_cache(maxsize=cache_size)
def fib(n): 
    if n < 2:
        return n
    return fib(n-1) + fib(n-2) …
Run Code Online (Sandbox Code Playgroud)

python decorator argparse python-3.x python-decorators

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

Django为decorator添加了可选参数

我有以下装饰和视图哪个工作正常.

装饰

def event_admin_only(func):
    """
    Checks if the current role for the user is an Event Admin or not
    """
    def decorator(request, *args, **kwargs):
        event = get_object_or_404(Event, slug=kwargs['event_slug'])

        allowed_roles = [role[1] for role in Role.ADMIN_ROLES]

        # get user current role
        current_role = request.session.get('current_role')

        if current_role not in allowed_roles:
            url = reverse('no_perms')
            return redirect(url)
        else:       
            return func(request, *args, **kwargs)
    return decorator
Run Code Online (Sandbox Code Playgroud)

视图

@event_admin_only
def event_dashboard(request, event_slug):
    pass
Run Code Online (Sandbox Code Playgroud)

但是我如何修改我的装饰器,以便它接受一个额外的参数,如下所示:

@event_admin_only(obj1,[...])
def event_dashboard(request, event_slug):
    pass
Run Code Online (Sandbox Code Playgroud)

python django decorator

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

长时间运行的python脚本的故障保护

这可能是有史以来最愚蠢的问题,但我想知道是否有办法在函数(最好是装饰器)周围编写一个包装器,这样你就可以在异常情况下捕获局部变量的内部状态.在这个职能中提出 它会捕获当地人创建它们,腌制它们,然后在没有引发异常的情况下处理它们,或者如果发现任何异常则将它们写入文件.

这太过于幻想了,还是有人因这样的事情而被骗了?

python

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

带参数的装饰器

代码如下

def my_dec(func):
    def wrap(w):
        t = func(w)
        return t * 4
    return wrap


@my_dec
def testing(n):
    return n


new = testing(3)
print(new)  # This prints 12
Run Code Online (Sandbox Code Playgroud)

这个示例工作正常,但是现在我尝试将以下内容添加到装饰器中@my_dec(100),我需要将给定的数字乘以100。

当我尝试这个

@my_dec(100)
def testing(n):
    return n
Run Code Online (Sandbox Code Playgroud)

我收到以下错误:

def my_dec(func):
    def wrap(w):
        t = func(w)
        return t * 4
    return wrap


@my_dec
def testing(n):
    return n


new = testing(3)
print(new)  # This prints 12
Run Code Online (Sandbox Code Playgroud)

如何将其传递100给装饰器?

python decorator python-decorators

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

在装饰器中使用部分时自我丢失

我正在尝试从使用另一个类的装饰器的类编写方法。问题是我需要存储在包含装饰器(ClassWithDecorator.decorator_param)的类中的信息。为了实现这一点,我使用部分注入 self 作为第一个参数,但是当我这样做时,使用装饰器的类中的 self 不知何故“丢失了”,最终我得到了一个错误。请注意,如果我partial()从中删除my_decorator()并且“self”将正确存储在*args.

查看代码示例:

from functools import partial


class ClassWithDecorator:
    def __init__(self):
        self.decorator_param = "PARAM"

    def my_decorator(self, decorated_func):
        def my_callable(ClassWithDecorator_instance, *args, **kwargs):
            # Do something with decorator_param
            print(ClassWithDecorator_instance.decorator_param)
            return decorated_func(*args, **kwargs)

        return partial(my_callable, self)


decorator_instance = ClassWithDecorator()


class WillCallDecorator:
    def __init__(self):
        self.other_param = "WillCallDecorator variable"

    @decorator_instance.my_decorator
    def decorated_method(self):
        pass


WillCallDecorator().decorated_method()
Run Code Online (Sandbox Code Playgroud)

我得到

PARAM
Traceback (most recent call last):
  File "****/decorator.py", line 32, in <module>
    WillCallDecorator().decorated_method()
  File "****/decorator.py", line 12, in my_callable
    return decorated_func(*args, …
Run Code Online (Sandbox Code Playgroud)

python python-3.x python-decorators

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

如何将等待/睡眠装饰器添加到步骤函数(行为)?

使用 Python/Selenium/Behave:

我想知道如何正确地将等待/睡眠装饰器添加到步骤函数中?

我用我的装饰器函数设置了一个 helper.py :

import time

def wait(secs):
    def decorator(func):
        def wrapper(*args, **kwargs):
            ret = func(*args, **kwargs)
            time.sleep(secs)
            return ret
        return wrapper
    return decorator

class Helper(object):
    pass
Run Code Online (Sandbox Code Playgroud)

在我的步骤文件中,我在行为装饰器之后调用等待装饰器以匹配步骤:

from behave import step
from features.helper import wait

@step('I observe a login error')
@wait(3)
def step_impl(context):
    #time.sleep(3)
    assert context.login_page.check_login_error() is not None
Run Code Online (Sandbox Code Playgroud)

但是,当我从功能文件执行该步骤时,没有执行等待/睡眠,并且断言失败。在这种情况下我该如何执行等待装饰器?

python python-decorators python-behave

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