4

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)
3
  • Well spotted. Thank you. I have just edited my question. Commented Jul 28, 2019 at 17:30
  • in this example yes but in real example I want to validate some data first, run some validation methods and if successful then return data to the child function for futher processing. Commented Jul 28, 2019 at 17:32
  • See example. you can add validation inside inner closure. Commented Jul 28, 2019 at 17:39

1 Answer 1

2

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
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.