gpt4 book ai didi

python - 常量和糖

转载 作者:太空狗 更新时间:2023-10-30 01:34:55 27 4
gpt4 key购买 nike

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

在使用该库时我想写的是:

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 函数在存储 mode 参数的默认值时没有定义(因此甚至没有修饰)。

这看起来不太好

我能想出的唯一解决方案导致了一种笨拙的语法,而且看起来也不太好。我为装饰器函数提供了与要被装饰的函数相同的属性。

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):
# ...

问题:

你能想到更好的方法吗?我真的很想坚持“一个声明来装饰”的事情。

最佳答案

您可以使用特殊变量作为对正在定义的函数的引用。

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

关于python - 常量和糖,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12554069/

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