Python 常数和糖

Python 常数和糖,python,constants,decorator,syntactic-sugar,Python,Constants,Decorator,Syntactic Sugar,我有一组我经常使用的函数,所以我想在库中收集它们。在开始编写库之前,我考虑将影响某些函数行为的常量存储在何处 使用该库时,我想写以下内容: import tools tools.collect(object_a, object_b, mode=tools.collect.RECURSIVE) 一般来说,函数应该能够接受的常量应该存储在函数本身中 为了实现这一点,我创建了一个decorator函数,它将传递的属性分配给修饰函数 def attr_decorator(**attrs): d

我有一组我经常使用的函数,所以我想在库中收集它们。在开始编写库之前,我考虑将影响某些函数行为的常量存储在何处

使用该库时,我想写以下内容:

import tools
tools.collect(object_a, object_b, mode=tools.collect.RECURSIVE)
一般来说,函数应该能够接受的常量应该存储在函数本身中

为了实现这一点,我创建了一个decorator函数,它将传递的属性分配给修饰函数

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):
    # ...
不需要天才就能意识到这本书读起来不好:

collect_d = attr_decorator(
    FLAT = 1 << 0,
    RECURSIVE = 1 << 1,
)
@collect_d
def collect(root, callback, mode=collect_d.RECURSIVE):
    # ...
collect\u d=attr\u decorator(

FLAT=1您可以使用一个特殊变量作为所定义函数的引用

class Attr(object):
    def __init__(self, name): self.name = name

class Attributor(object):
    def __getattr__(self, x): return Attr(x)

_ = Attributor()

def attr_decorator(**attrs):
    def decorator(f):
        for k, v in attrs.iteritems():
            setattr(f, k, v)
        f.func_defaults = tuple(attrs[t.name] if isinstance(t, Attr) else t for t in f.func_defaults)
        return f
    return decorator    

@attr_decorator(
    FLAT = 1 << 0,
    RECURSIVE = 1 << 1,
)
def collect(a, b, mode=_.RECURSIVE, foo=123):
    print a, b, mode, foo

collect(100,200) # 100 200 2 123
类属性(对象):
def _uinit _;(self,name):self.name=name
类属性(对象):
def\uuu getattr\uuu(self,x):返回Attr(x)
_=属性()
def attr_decorator(**attrs):
def装饰器(f):
对于attrs.iteritems()中的k,v:
setattr(f,k,v)
f、 func_defaults=元组(attrs[t.name],如果是instance(t,Attr),则为t,在f.func_默认值中为t)
返回f
返回装饰器
@属性装饰器(
平面=1
一般来说,函数应该能够接受的常量应该存储在函数本身中

我不同意这种说法。这些常量是函数外部接口的一部分,旨在供调用方使用。将它们定义为
工具的一部分有什么错

COLLECT_RECURSIVE=0
COLLECT_NONRECURSIVE=1
COLLECT_OTHER=2

def collect(a,b,mode):
    pass
呼叫者:

import tools
tools.collect(object_a, object_b, mode=tools.COLLECT_RECURSIVE)

有两种选择:1)全局常量,2)您的装饰器与functools的操作密切相关。partial,您确定您没有重新发明轮子吗?非常聪明,先生。这看起来确实是一个很好的解决方案+1(但我会等待其他可能的答案)好吧,这是我个人为这个库存储常量的选择
COLLECT_RECURSIVE=0
COLLECT_NONRECURSIVE=1
COLLECT_OTHER=2

def collect(a,b,mode):
    pass
import tools
tools.collect(object_a, object_b, mode=tools.COLLECT_RECURSIVE)