嗨我需要一个函数,它将获取一个函数并返回一个将运行该参数函数的函数,例如.1000次,每次评估它的论点.我有这样的事情:
def runner(f):
def inner(*args):
for i in xrange(1000):
f(*args)
return inner
Run Code Online (Sandbox Code Playgroud)
但似乎这样的调用:runner(f)(random.randint(1,UPPER_BOUND))使用相同的参数运行f 1000次.怎么做正确?
我有以下装饰和视图哪个工作正常.
装饰
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 myFunc( a, b ):
def innerFunc( c ):
print c
innerFunc( 2 )
print a, b
Run Code Online (Sandbox Code Playgroud)
如何直接访问内部函数?我想要格式化该函数的对象/地址
<function innerFunc at 0xa0d5fb4>
Run Code Online (Sandbox Code Playgroud)
我尝试使用myFunc._ getattr _('innerFunc'),但这不起作用.
我在这看起来似乎很愚蠢.但是,我正在写一些python代码,这件事让我感到震惊.在python中有一些叫做装饰器的东西,它们用@"around"函数表示并使用它们:
class PlotABC(metaclass=ABCMeta):
@property
def figure(self):
if self._figure is None: self.__create_figure()
return self._figure
@abstractmethod
def _prepare_series(self):
pass
Run Code Online (Sandbox Code Playgroud)
我也知道设计模式的细节,我知道有些模式称为装饰器.然后我曾经想过,"嘿,也许这个名字相似并不是一个奇怪的巧合."
我读过wiki:Decorator模式和很棒的答案如何制作一系列函数装饰器?(几乎全部).
在我看来,python的装饰器语义非常强大,可以用来实现设计模式.因为它们允许包围函数和方法.虽然,我仍然感到困惑,因为我对设计模式缺乏经验.我也不知道有这种专门机制的语言.
有经验的python和设计模式的人是否可以故意创建python语义来创建装饰模式?它是更多,更少,还是意味着不同的东西?
并且可能会说明如何声明方法摘要或属性正在装饰它?
我一直在测试这个缓存方法/代码:http: //code.activestate.com/recipes/498245-lru-and-lfu-cache-decorators/?c = 15348
在某些情况下,我得到这个(或类似的)错误:"AttributeError:'str'对象没有属性' module '"
这里是代码示例,这些工作正常:
if __name__ == '__main__':
@lru_cacheItem(maxsize=20)
def f(x, y):
return 3*x+y
domain = range(5)
from random import choice
for i in range(1000):
r = f(choice(domain), choice(domain))
print('Hits:{0}'.format(f.hits), 'Misses:{0}'.format(f.misses))
@lfu_cacheItem(maxsize=20)
def f(x, y):
return 3*x+y
domain = range(5)
from random import choice
for i in range(1000):
r = f(choice(domain), choice(domain))
print('Hits:{0}'.format(f.hits), 'Misses:{0}'.format(f.misses))
@lru_cacheItem(maxsize=20)
def myString(a, b):
return '{0} and {1}'.format(a, b)
a = 'crap'
b = 'shit'
for i in range(1000):
r …Run Code Online (Sandbox Code Playgroud) 我正在用这种方式装饰所有方法
import inspect
def decallmethods(decorator, prefix='test_'):
def dectheclass(cls):
for name, m in inspect.getmembers(cls, inspect.ismethod):
if name.startswith(prefix):
setattr(cls, name, decorator(m))
return cls
return dectheclass
@decallmethods(login_testuser)
class TestCase(object):
def setUp(self):
pass
def test_1(self):
print "test_1()"
def test_2(self):
print "test_2()"
Run Code Online (Sandbox Code Playgroud)
这是有效的,但它适用于顶部,如果我有其他装饰器.
我的意思是
现在的结果是
@login_testuser
@other
def test_2(self):
print "test_2()"
Run Code Online (Sandbox Code Playgroud)
但我想要
@other
@login_testuser
def test_2(self):
print "test_2()"
Run Code Online (Sandbox Code Playgroud) 使用闭包而不是__all__限制Python模块公开的名称是一个好主意吗?这将阻止程序员意外地使用错误的名称(import urllib; urllib.os.getlogin())模块()以及避免" from x import *"命名空间污染__all__.
def _init_module():
global foo
import bar
def foo():
return bar.baz.operation()
class Quux(bar.baz.Splort): pass
_init_module(); del _init_module
Run Code Online (Sandbox Code Playgroud)
使用相同的模块__all__:
__all__ = ['foo']
import bar
def foo():
return bar.baz.operation()
class Quux(bar.baz.Splort): pass
Run Code Online (Sandbox Code Playgroud)
函数可以采用这种方式来避免污染模块名称空间:
def foo():
import bar
bar.baz.operation()
Run Code Online (Sandbox Code Playgroud)
这对于希望帮助用户在交互式内省期间将其API与包和其他模块的API的使用区分开来的大型包可能会有所帮助.另一方面,也许IPython应该__all__在标签完成期间简单地区分名称,并且更多用户应该使用允许它们在文件之间跳转以查看每个名称的定义的IDE.
我正在尝试了解Python装饰器,并且想更详细地了解闭包如何应用,例如在此备注上下文中:
def memoize(f):
memo = {}
def helper(x):
if x not in memo:
memo[x] = f(x)
return memo[x]
return helper
@memoize
def fib(n):
if n in (0,1):
return n
return fib(n - 1) + fib(n - 2)
Run Code Online (Sandbox Code Playgroud)
我了解即使程序流不再位于该封闭范围内,也memoize将返回绑定到memo其封闭范围内的值的函数helper。因此,如果memoize反复调用,它将根据的当前值返回变化的功能序列memo。我也了解这@memoize是语法糖,它导致调用fib(n)被替换为memoize(fib(n))。
我苦苦挣扎的是nin 的调用值如何fib(n)有效地转换为xin helper(x)。大多数关于闭包的教程似乎都没有明确指出这一点,或者他们隐约地说一个函数“关闭”了另一个函数,这听起来像是魔术。我可以看到如何使用语法,但是希望更好地掌握这里发生的事情以及代码执行时传递的对象和数据。
我很难理解如何将参数传递给装饰器内的包装器函数.举一个简单的例子:
def my_decorator(func):
def wrapper(func_arg):
print('Before')
func(func_arg)
print('After')
return wrapper
@my_decorator
def my_function(arg):
print(arg + 1)
my_function(1)
Run Code Online (Sandbox Code Playgroud)
我有一个函数,需要1个参数,它被装饰.我在理解func_arg如何工作方面遇到了麻烦.调用my_function(1)时,值1如何传递给包装器.根据我对此的一点理解,my_function被一个新函数'替换',如:my_function = my_decorator(my_function).
print(my_function)
<function my_decorator.<locals>.wrapper at 0x7f72fea9c620>
Run Code Online (Sandbox Code Playgroud) 我正在尝试克服自开始以来我一直避免使用的最终基本 Python 功能之一:装饰器。我不像使用 list-comps 那样对它进行操作,而且我不明白装饰器声明中的内部函数是如何工作的。
这是我的意思的一个例子。鉴于此块代码:
def outer(func):
def inner(*args, **kwargs):
print('Hi my name is ')
return func(*args, **kwargs)
return inner
@outer
def decorated(name):
print(name)
decorated('Bob')
Run Code Online (Sandbox Code Playgroud)
我知道这将打印
def outer(func):
def inner(*args, **kwargs):
print('Hi my name is ')
return func(*args, **kwargs)
return inner
@outer
def decorated(name):
print(name)
decorated('Bob')
Run Code Online (Sandbox Code Playgroud)
但我不明白的是如何inner获得任何*args或**kwargs从decorated()
我的理解是
@outer
def decorated(name):
print(name)
decorated("Bob")
Run Code Online (Sandbox Code Playgroud)
相当于outer(decorated("Bob"))。如果是这种情况,如何inner()能够访问name参数?撇开语法问题不谈,我希望内部声明看起来像def inner(func.args, func.kwargs):
这里发生了什么?我有什么误解?
python ×10
decorator ×4
closures ×2
python-3.x ×2
caching ×1
django ×1
function ×1
memoization ×1
python-2.7 ×1