我有一组我经常使用的函数,所以我想将它们收集到一个库中。在开始编写库之前,我在考虑将影响某些函数行为的常量存储在哪里。
使用该库时我想写的内容如下:
import tools
tools.collect(object_a, object_b, mode=tools.collect.RECURSIVE)
一般来说,函数应该能够接受的常量应该存储在函数本身中。
为了实现这一点,我创建了一个装饰器函数,将传递的属性分配给装饰函数。
def attr_decorator(**attrs):
def decorator(f):
for k, v in attrs.iteritems():
setattr(f, k, v)
return f
return decorator
这个装饰器可以这样使用:
@attr_decorator(
FLAT = 1 << 0,
RECURSIVE 1 << 1,
)
def collect(a, b, mode):
# ...
到目前为止,这工作得很好。
但是默认参数呢?
@attr_decorator(
FLAT = 1 << 0,
RECURSIVE 1 << 1,
)
def collect(a, b, mode=collect.RECURSIVE):
# ...
这不起作用,因为在存储模式参数的默认值时未定义collect函数(因此甚至没有修饰)。
这看起来不太好
我能想出的唯一解决方案导致语法很尴尬,而且看起来不太好。我赋予装饰器功能与将要装饰的功能相同的属性。
def attr_decorator(**attrs):
def decorator(f):
for k, v in attrs.iteritems():
setattr(f, k, v)
return f
for k, v in attrs.iteritems():
setattr(decorator, k, v)
return decorator
不需要天才就可以认识到这并不好阅读:
collect_d = attr_decorator(
FLAT = 1 << 0,
RECURSIVE = 1 << 1,
)
@collect_d
def collect(root, callback, mode=collect_d.RECURSIVE):
# ...
问题:
你能想出更好的方法吗?我真的很想坚持“一个声明来装饰”的事情。