gpt4 book ai didi

python - 使用装饰器添加返回添加了属性的内部函数

转载 作者:行者123 更新时间:2023-11-28 18:49:45 24 4
gpt4 key购买 nike

我有大量函数在尝试保存对象时作为测试运行,因此我创建了一种方法来更方便地将此方法注册为对象的约束(测试)。

我对在我的解决方案中使用装饰器感到困惑。我打算做什么:

  • 创建一个装饰器,将属性添加到对象中的方法
  • 装饰我想标记为约束的方法。
  • 在我的对象上循环所有方法并调用以执行所有具有标志的方法

用装饰器不行,自己加flag不行。

代码如下:

from functools import wrap

def constraint(func):
@wraps(func)
def inner(*args, **kwargs):
func._is_constraint = True # Here after returning the function I add a flag
return func(*args, **kwargs)
return inner

class Record(object):
param1 = 100 # some defaults
param2 = 20

@constraint # This dont works
def check_test1(self):
if param1 < 0:
return 'No value less than zero'

# This works fine
def check_test2(self):
if param2 < 0:
return 'No value less than zero'
check_test2._is_constraint = True

def a_random_method(self):
print 'some random thing'

那么我正在尝试的是:

>>> rec = Record()
>>> rec.param1 = -100
>>> rec.param2 = -100
>>> for prop in dir(rec):
... if hasattr(getattr(rec, prop), '_is_constraint'):
... constraint = getattr(rec, prop)
... print prop, constraint()
...
'check_param2: No value less than zero'
>>>

看到 check_param1 没有被执行。

那么,我怎样才能使用装饰器让它工作呢?可能吗?

我正在尝试在这个特殊情况下使用 https://gist.github.com/mariocesar/4684561

最佳答案

好吧,我首先看到的是,您想将参数添加到装饰器中的函数对象,而不是闭包;当从装饰范围调用函数时会调用闭包,因此在闭包中标记它是在事后进行:

def constraint(func):
func._is_constraint = True
@wraps(func)
def inner(*args, **kwargs):
return func(*args, **kwargs)
return inner

此外,如果您所做的只是在闭包中直接调用 func 而没有添加任何功能,只是标记它,那么闭包是完全多余的:

 def constraint(func):
func._is_constraint = True
return func

在这种情况下,使用不同的模式可能会更好:

class ConstraintsType(type):

def __new__(cls, name, bases, attrs):

attrs['constraint_names'] = []
for attr in attrs:
if attr.startswith('constraint_'):
attrs['constraint_names'].append(attr)
return super(ConstraintsType, cls).__new__(cls, name, bases, attrs)

class Constraints(object):

__metaclass__ = ConstraintsType

@property
def constraints(self):

for name in self.constraint_names:
yield getattr(self, name)

class Record(Constraints):

def __init__(self, params=(100, 20)):

self.params = params

def constraint_greater_than_0(self, value):

return value > 0

def run(self):

for index, value in enumerate(self.params):
for func in self.constraints:
if not func(value):
print 'param %d (%s) did not satisfy constraint %s' % (index, value, func.__name__)

Record().run()
for value_set in ((-100, -100), (0, 0), (-1,1), (1,-1)):
Record(value_set).run()

关于python - 使用装饰器添加返回添加了属性的内部函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14709244/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com