7

here I want to call web service function only once throughout the program. how to accomplish this anybody suggest me

import sys,os

def web_service(macid):
        # do something

if "__name__" = "__main__" :
      web_service(macid)
thefourtheye
  • 233,700
  • 52
  • 457
  • 497
Ankush
  • 103
  • 1
  • 1
  • 3
  • 2
    `"__name__" = "__main__"` will not work. You might want to do `__name__ == "__main__"`. Assignment operator (`=`) is not the same as equality operator (`==`). Also check [`__name__`](https://docs.python.org/3/library/__main__.html), it is not `"__name__"`. – thefourtheye Apr 21 '15 at 06:01
  • 1
    @thefourtheye I think you meant `__name__ == "__main__"` – Leon Apr 21 '15 at 06:02
  • `if __name__ == '__main__':` – Peter Wood Apr 21 '15 at 06:02
  • @thefourtheye i want to call webservice function only once.how to achieve this . Can you suggest me,if __name__ == '__main__": that i know – Ankush Apr 21 '15 at 06:06
  • Generic solution: Once it has been called, set a variable to `true` or something, check if that variable is `true`, `return` immediately. Or you'll have to give a few more details about why you want this. – deceze Apr 21 '15 at 06:15
  • If you're using Python 3.2 or later you can use [`functools.lru_cache`](https://docs.python.org/3/library/functools.html#functools.lru_cache). – Peter Wood Apr 21 '15 at 20:09

2 Answers2

10

This is how I would to that:

i_run_once_has_been_run = False

def i_run_once(macid):
    global i_run_once_has_been_run

    if i_run_once_has_been_run:
        return

    # do something

    i_run_once_has_been_run = True

@Vaulstein's decorator function would work too, and may even be a bit more pythonic - but it seems like a bit overkill to me.

rickcnagy
  • 1,774
  • 18
  • 24
  • What if you have two functions you only want to run once? – Peter Wood Apr 21 '15 at 07:05
  • 1
    @PeterWood then you would use two globals, I guess. I think at that point the decorator makes sense, but for a single function just a global boolean is best. – rickcnagy Apr 21 '15 at 13:57
  • What would you name the other global? – Peter Wood Apr 21 '15 at 15:24
  • Good point - see my edit. I guess if `i_run_once_also()` were in play we would name the global `i_run_once_also_has_been_run`. But again, I think the decorator solution is better there. – rickcnagy Apr 21 '15 at 15:26
  • Rather than a global, perhaps use an attribute (`i_run_once.has_been_run = True`), and test it with `getattr(i_run_once, 'has_been_run', False)`. – user2846495 Apr 16 '20 at 14:49
1

Using class,

class CallOnce(object):
    called = False

    def web_service(cls, macid):
        if cls.called:
            print "already called"
            return
        else:
            # do stuff
            print "called once"
            cls.called = True
            return


macid = "123"
call_once_object = CallOnce()
call_once_object.web_service(macid)
call_once_object.web_service(macid)
call_once_object.web_service(macid)

Result is,

I have no name!@sla-334:~/stack_o$ python once.py 
called once
already called
already called
pnv
  • 2,985
  • 5
  • 29
  • 36