How to make a few lines of function execute only once in python? preferably using lambda?

Question:

I have one python function as shown below.

def save_eng(request):
    flag = "true"
    if flag == "true" :
        db = Create()
        db.CreateSubmit_EngineerTable()
        flag = "false"
    else:
        pass

Now I want to call the CreateSubmit_Engineer() only once i.e when its called for the first time. I’ll be calling this function many times but it shouldn’t create the table again and again. I have used the flag variable which isn’t solving my purpose.The flag gets assigned to “true” value when I’m calling this function. I know I’m so close just need small hint.Any help is greatly appreciated. Can the above function be written in any other better way ?

Asked By: d-coder

||

Answers:

You can use a decorator for this.

Using class based decorator:

class callonce(object):

    def __init__(self, f):
        self.f = f
        self.called = False

    def __call__(self, *args, **kwargs):
        if not self.called:
            self.called = True
            return self.f(*args, **kwargs)
        print 'Function already called once.'

Using function attribute:

from functools import wraps

def callonce(f):

    @wraps(f)
    def wrapper(*args, **kwargs):
        if not wrapper.called:
            wrapper.called = True
            return f(*args, **kwargs)
        print 'Function already called once.'
    wrapper.called = False
    return wrapper

Now add the decorator above your function:

@callonce
def func():
    print "Creating Table"

Demo:

>>> func()
Creating Table
>>> func()
Function already called once.
>>> func()
Function already called once.
Answered By: Ashwini Chaudhary

Alternatively you can use a class here. Put the code to create the table on constructor i.e. __init__(self) and then create an object of the class and call the save_eng() as many times as per your requirement

Class Engineer(object):
    def __init__(self):
        self.db = Create()
        self.db.CreateSubmit_EngineerTable()
    def save_eng(self, request):
        # Your other code specific to save_eng
        # you can use self.db here
        pass


# Create instance of class
eng = Engineer()
eng.save_eng(request)
Answered By: Ansuman Bebarta

If you do not pass any parameters, you can use functools.lru_cache:

from functools import lru_cache


@lru_cache(maxsize=1)
def func():
    print "Creating Table"
Answered By: Q. Qiao
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.