KinWolf
KinWolf

Reputation: 175

How to define a callable that can only be called once?

To demonstrate what I want to do, here's a piece of code:

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

To test our class, I proceed as follows:

for i in range(2):

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

The expected result should be like this:

called once
123
already called

Except I got this as a result:

called once
123
called once
123

The idea is to store the value 123 only once in the call variable without using global variable.

Upvotes: 2

Views: 1249

Answers (3)

LevB
LevB

Reputation: 953

You don't need a class for this. Functions can have their own attributes.

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

web_service(5)
web_service(6)      

Output:

called once
already called

Upvotes: 2

0p3r4t0r
0p3r4t0r

Reputation: 693

So you're trying to save some state. What you could do is use an object instead.

class Test():
    def __init__(self):
        self.called = False

    def call_me_maybe(self):
        if (not self.called):
            print('Hey, you called?')
            self.called = True
        else:
            print("Stop calling me it's getting weird")

test = Test()
test.call_me_maybe() #-> Hey, you called?
test.call_me_maybe() #-> Stop calling me it's getting weird

Upvotes: 4

Barmar
Barmar

Reputation: 781750

cls.called is an attribute of the instance, not the class. Each time you create a new object, it gets its own attribute, which defaults to False.

If you want to share this among all the instances, you should use CallOnce.called, not cls.called.

BTW, the conventional name for the first argument of instance methods is self. cls is used for class methods.

Upvotes: 10

Related Questions