我想将“黑匣子”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) 我试图定义一个装饰器来执行一个类方法,首先尝试它,如果检测到错误,则提出它并提及失败的方法,以便用户可以看到哪个方法是错误的。
在这里,我展示了我的代码的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 。
我想知道装饰函数是否有办法引用装饰器包装器创建的对象.当我想要使用装饰器时,我的问题出现了:
但是,修饰函数需要引用包装器创建的图形.装饰函数如何引用该对象?我们是否必须诉诸全局变量?
这是一个简短的例子,我在装饰函数中引用了一个在包装器中创建的变量(但是我没有设法在没有使用全局变量的情况下执行此操作):
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)
我知道这很容易在课堂上完成,但我出于好奇而问这个问题.
我希望 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 脚本。
main()将解析参数,并将它们传递给中间函数(caller_func在代码示例中)
然后,中间函数将调用一个用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) 我有以下装饰和视图哪个工作正常.
装饰
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) 这可能是有史以来最愚蠢的问题,但我想知道是否有办法在函数(最好是装饰器)周围编写一个包装器,这样你就可以在异常情况下捕获局部变量的内部状态.在这个职能中提出 它会捕获当地人创建它们,腌制它们,然后在没有引发异常的情况下处理它们,或者如果发现任何异常则将它们写入文件.
这太过于幻想了,还是有人因这样的事情而被骗了?
代码如下
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给装饰器?
我正在尝试从使用另一个类的装饰器的类编写方法。问题是我需要存储在包含装饰器(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/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)
但是,当我从功能文件执行该步骤时,没有执行等待/睡眠,并且断言失败。在这种情况下我该如何执行等待装饰器?