0

I want a class to call my function on a certain event. My question is, is it good practice to check for "None" to check if the Function "Pointer" has been initialized? Are there any other gotchas using this pattern?

In class:

class Consumer(object):
    _functionCallBack = None

    def __init__(self, hostName):
        self._hostName = hostName

    def SetCallBack(self, funcCallback):
        self._functionCallBack = funcCallback

    def HandleMessage(self, body):
        print(" [x] Received %r" % body)
        if self._functionCallBack is not None:
            self._functionCallBack(body)

In calling code:

def handleMessageReceived(message):
    print("In call back", message);

def main():
    Consumer = Consumer("hostname")
    consumer.SetCallBack(handleMessageReceived)
    consumer.Start()


if __name__ == "__main__" : main()

I was unable to find any best practices for this - if there are some in the Python docs can you let me know.

5
  • 1
    shoudn't _functionCallBack = None be part of the __init__ method? Commented Jan 27, 2017 at 12:14
  • Side note: you need to declare global _functionCallBack inside every function that changes its value. Commented Jan 27, 2017 at 12:25
  • @barakmanos - even if it is in a class and you are using self to access it? Commented Jan 27, 2017 at 12:42
  • @barakmanos - actually, I didn't have self in first post - updated now Commented Jan 27, 2017 at 12:43
  • I don't know, I see a global variable up there. No self, and not inside a class. AFAIK, if you want to change it inside a function, then you need to declare it global in that function. Commented Jan 27, 2017 at 12:49

2 Answers 2

1

A solution here (from a design POV) would be to use the NullObject pattern - in this case make the default functionCallback a no-op function so you don't have to test anything. Also, you may want to pass the callback at instanciation instead of adding it later (unless in your real code you need to do so at different stages of course)

def noop(message):
    pass

class Consumer(object):
    def  __init__(self, hostname, callback=noop):
        self._hostname = hostname
        self._callback = callback

    def set_callback(self, callback):
        self._callback = callback

    def handle_message(self, body):
        logger.info(" [x] Received %r", body)
        self._callback(body)

Now whether this is better than testing against None is left to the reader's appreciation. The pros: you don't have a special case, the cons: you have a possibly useless func call. If you expect Consumer instances to get an effective callback most of the time the "no-op callback" solution might be slightly cleaner, else the "check against None" is perfectly valid.

Sign up to request clarification or add additional context in comments.

Comments

1

You should normally go with the if ... is not None: construct to detect uninitialised variables. An option is to use a try/catch clause, but your situation is not about an unexpected alternate flow and a try/catch could be avoided.

Also see: How to test whether a variable has been initialized before using it?

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.