Amir Afianian
Amir Afianian

Reputation: 2797

How to delay evaluation of python expression passed inside __init__

I have a scenario where I want to use logical operators between classes that are passed to init of another class. But, I want to postpone the evaluation of the operators to calling the object Basically inside __call__. There, I want to pass some more arguments that are needed for the logical operators.

Basically, I want to achieve this interface:

IsAllowed(classes=[Auth1('some_value') | Auth2('some_other_value')]

But, I want to postpone the evaluation of classes=[Auth1('some_value') | Auth2('some_other_value') to the time where __call__ is called on IsAllowed and pass some extra args that are used in the logical operation.

And this is how Auth classes could look like under the hood:

class Auth:

    def __or__(self, other):
        return self.has_perm(run_time_arg) or other.has_perm(run_time_arg)

Is there a way to achieve that?

Upvotes: 2

Views: 67

Answers (2)

Andrew Jaffe
Andrew Jaffe

Reputation: 27097

How about just deferring until call time by not actually executing the __or__ until then:


def IsAllowedAuth12(value1, value2):

    return IsAllowed(classes=[Auth1(value1) | Auth2(value2)])

Upvotes: 1

Charles Duffy
Charles Duffy

Reputation: 295659

If you want to allow deferred execution (with some_value provided at that later time), rearrange the API to let your caller pass a lambda:

IsAllowed(classesFn = lambda value: [Auth1(value) | Auth2(value)])

...and then have the callee invoke that function to get the value it returns.


This might look something like:

class IsAllowed(object):
    def __init__(self, classesFn=None):
        self.classesFn = classesFn
    def __call__(self, value):
        classes = self.classesFn(value)
        # do logic using 'classes' here

Upvotes: 4

Related Questions