I don't think a decorator is appropriate here. A class seems more suitable precisely because of the problem you're facing. Something like this:
class Test(object):
def __init__(self, test_value):
self.test_value = test_value
def test(self):
print "The value I need is", self.test_value
self._inner_test()
def _inner_test():
print "running test"
if __name__ == '__main__':
args = get_args()
t = TestClass(args.test_value)
t.test()
How exactly to structure the class is not clear from the example you have given and would depend on what you're actually doing, but I think something in this vein will provide you with a more robust solution than trying to shoehorn this into decorators.
Classes are designed to maintain state and provide modified behavior based on that state. That is what you're doing. Your application has state that modifies its behavior. Decorators are designed to wrap extra, static functionality around an existing method.
However, if that is unsuitable, another alternative is to simply allow your arguments to be global. Something along the lines of this:
config.py
import argparse
test_value = None
def parse_args():
parser = argparse.ArgumentParser()
parser.add_argument('-t', '--test_value', dest='test_value', required=True, default="sample value")
args = parser.parse_args()
return args
def configure():
global test_value
args = parse_args()
test_value = args.test_value
main.py
from functools import wraps
import config
def decorator_example(f):
@wraps(f)
def f_example(*args, **kwargs):
print "The value I need is", config.test_value
return f(*args, **kwargs)
return f_example
@decorator_example
def test():
print "running test"
if __name__ == '__main__':
config.configure()
test()
One nice side of this solution is that it gives you an obvious way to also supplement your arguments with a configuration file. Note that this should actually work since config.test_value
is not actually read until test
is called.