Dariusz Krynicki
Dariusz Krynicki

Reputation: 2718

python wrap function with function

I have these two functions below. I want to run validate first then child but I want to decorate child with validate so I can tell it to run validate on the given input first and then pass the output to child to run on it.

def validate(x, y):
    print(x, y)
    x = x+2
    y = y +1
    return x, y


def child(x, y):
    print(x)
    print(y)
    return x, y

How can I do it?

Obviously, this does not work:

def validate(x):
    print(x)
    x = x+2
    return x

@validate
def child(x):
    print(x)
    return x

I want to achieve something like this but in decorator way:

child(validate(2))

EDIT:

I have some method 'data_parsing' that takes the input and does some login on the inputed data. The data may be malfunction so I have create a class with methods which validate the inputted data first. I instantiate the class and run the validation first raising exceptions if data is malformed. if successfull i step to next function call data_parsing() which takes data and processes it. so the logic is:

def execute(data):
    validator_object(data).run()
    data_parsing(data)

EDIT:

def validator(fnc):
    def inner(*aaa):
        a,b = aaa
        a += 4
        return fnc(a,b)
    return inner

@validator
def child(*aaa):
    a,b = aaa
    print(a)
    return a

a = 1
b = 2
child(a, b)

Upvotes: 4

Views: 9145

Answers (1)

RomanPerekhrest
RomanPerekhrest

Reputation: 92854

Be aware that @decorator form is applied on function declaration phase, it'll wrap the target function at once.

You may use the following implementation for your case:

def validate(f):
    @functools.wraps(f)
    def decor(*args, **kwargs):
        x, y = args
        if x <= 0 or y <= 0:
            raise ValueError('values must be greater than 0')
        print('--- validated value', x)
        print('--- validated value y', y)
        x = x+2
        y = y+1
        res = f(x, y, **kwargs)
        return res
    return decor

@validate
def child(x, y):
    print('child got value x:', x)
    print('child got value y:', y)
    return x, y


child(3, 6)
child(0, 0)

Sample output:

--- validated value x 3
--- validated value y 6
child got value x: 5
child got value y: 7
Traceback (most recent call last):
  File "/data/projects/test/functions.py", line 212, in <module>
    child(0, 0)
  File "/data/projects/test/functions.py", line 195, in decor
    raise ValueError('values must be greater than 0')
ValueError: values must be greater than 0

Upvotes: 2

Related Questions