创建装饰器/缓存以检查全局变量

时间:2017-05-11 05:18:52

标签: python global-variables decorator nameerror

我有很多函数使用一些全局变量来保存一个在整个库中重用的对象,例如:

from some.other.lib import Object1, Object2, Object3, Object4, Object5

def function1(input):
    global _object1
    try:
        _object1
    except NameError:
        _object1 = Object1
    return _object1.func1(input)


def function2(input):
    global _object2
    try:
        _object2
    except NameError:
        _object2 = Object2
    # Use function1 to do something to the input
    return _object2.func2(function1(input))


def function3(input):
    global _object3
    try:
        _object3
    except NameError:
        _object3 = Object3
    # Use function1 to do something to the input.
    return _object3.func3(function1(input))


def function4(input):
    global _object4
    try:
        _object4
    except NameError:
        _object4 = Object4
    return _object4.func4(input)


def function5(input):
    global _object5
    try:
        _object5
    except NameError:
        _object5 = Object5
    # Use function4 to do something to the input.
    return _object5.func5(function4(input))

有没有办法编写装饰器,以便检查全局变量的代码不需要为每个function*手动硬编码?

E.g。类似的东西:

def exist_decorator(_object, _class):
    try:
        _object
    except NameError:
        _object = _class
    return _object

因此function4()的实际类实现如下:

def function4(input):
    global _object4
    exist_decorator(_object4, Object4)
    return _object4.func4(input)

在Python中使用装饰器在语法上是否可以这样?如果没有,我还能如何创建装饰器/缓存以检查全局变量?

1 个答案:

答案 0 :(得分:1)

我猜你只想缓存一些值。为此,在没有滥用任何隐藏功能的情况下,正常Python中的直接方法是这样的:

cache = {}

def function1(input):
    try:
        object1 = cache['object1']
    except KeyError:
        object1 = cache['object1'] = Object1
    return object1.func1(input)

与其他功能类似。

您还可以通过在函数对象中存储所有内容来避免使用静态全局变量cache

def function1(input):
    try:
        object1 = function1.object1
    except AttributeError:
        object1 = function1.object1 = Object1
    return object1.func1(input)

这是可能的,因为函数是可以添加属性的任意对象。但有些人可能会将此称为滥用和不洁的代码。在这种情况下,请先与您的团队讨论,然后在使用之前将其添加到此团队或项目的已用技术列表中。

我更喜欢使用可变参数的隐藏功能:

def function(input, object1Cache=[None]):
    if object1Cache[0] is None:
        object1Cache[0] = Object1
    return object1Cache[0].func1(input)

这适用于Python,因为作为函数参数的默认值的列表仍然是可变的并且将保持其值。

同样,这可能被视为不洁和滥用,因此在使用之前与您的团队讨论这个问题,并在项目说明中记录使用此技术。