函数装饰器指定def的前两行?

时间:2016-09-06 18:44:04

标签: python python-3.x

我在python 3.5:

我的一些python函数中有一个重复模式。对于大量的类集合,前两行是:

obj_a = <..... obtain something I need.....>
obj_b = <..... obtain another thing I need....>

我在这里简化了它,但获取obj_aobj_b的过程并不是一个内容......我想避免在更多地方重复此代码比util函数更优雅的方式来获取obj_aobj_b(例如obj_a = getObjectA() ...)

有没有办法获取这些行并将它们作为函数的装饰器的一部分,我有类似的东西:

@function_where_I_need_my_objects
def foo:
  <....do something with obj_a and obj_b already initialized....>

3 个答案:

答案 0 :(得分:1)

obj_aobj_b听起来很像州。

class Thing:
    def __init__(self):
        # These could also be class attributes instead
        # if they can be initialized when Thing is first
        # defined.
        self.obj_a = ...
        self.obj_b = ...

    def foo(self):
        # use self.obj_a and self.obj_b

t = Thing()
t.foo()

定义一个返回obj_aobj_b周围的闭包的装饰器也是可能的。

def decorator(f):
    obj_a = ...
    obj_b = ...
    def _():
       # use obj_a and obj_b
    return _

@decorator
def foo():
    ...

然而,简单地编写返回两个对象的函数几乎不再灵活,并且让调用者使用他们喜欢的任何名称:

def _get_a_b():
    a = ...
    b = ...
    return a, b

def foo():
   obj_a, obj_b = _get_a_b()
   ...

def bar():
    a1, a2 = _get_a_b()
    ...

答案 1 :(得分:-1)

你可以做类似下面的事情,它创建的变量在调用时会有效地成为函数的本地变量。这使用了eval(),如果在不受信任的输入上使用它可能是不安全的,但这不是用于执行已修饰函数的已编译字节代码的情况(但告诫emptor )。

def local_vars(**kwargs):
    """ Create decorator which will inject specified local variable(s) into
        function before executing it.
    """
    def decorator(fn):
        def decorated():
            return eval(fn.__code__,
                        {k: v() for k, v in kwargs.items()}) # call funcs
        return decorated
    return decorator

def get_object_a(): return 13
def get_object_b(): return 42

# create abbreviation for the long decorator
obj_decorator = local_vars(obj_a=get_object_a, obj_b=get_object_b)

@obj_decorator  # apply decorator
def test():
    print(obj_a)
    print(obj_b)

test()

输出:

13
42

答案 2 :(得分:-3)

您可以将这两个对象放在基类中:

class TheBaseClass:
    obj1 = something
    obj2 = something_else

并在您需要的类的函数中继承它:

class Class1(TheBaseClass):
    def func1(self):
       a = self.obj1  # make use of it
       b = self.obj2  # make use of it