Home > OS >  Alternative to Global Variables?
Alternative to Global Variables?

Time:03-03

This is my first stack overflow post. I'm very new to python. I've got a function which connects to a websocket stream and then prints results approximately every 100-500 milliseconds.

def generator:
    endpoint = "wss://example.websocket.test"
    def on_message(self, message):
        data = float(message)
        print(data)
    ws = websocket.WebsocketApp(endpoint, on_message = on_message)
    ws.run_forever()
generator()

The issue is that this function would print out redundant information. I only want information to be printed out if it is a new value different from the last.

OUTPUT:
200
100
200
200
300

I added an if statement to my function

last = 0.0
def generator:
    endpoint = "wss://example.websocket.test"
    def on_message(self, message):
        data = float(message)
        global last
        if data != last:
            print(data)
            last = data
    ws = websocket.WebsocketApp(endpoint, on_message = on_message)
    ws.run_forever()
generator()

This does a great job and only print new values. However I have been trying to figure out how to do this without using global variables and I cannot seem to find any info. This code never seems to work if I make the last variable local to the on_message(): function. Any advice appreciated!

CodePudding user response:

One option is to use a mutable object; that way you can mutate the actual object that last points to rather than rebinding last to a different object (and using global to do it across different scopes).

    last = [0.0]
    def on_message(wsapp, message):
        data = float(message)
        if data != last[0]:
            print(data)
            last[0] = data

In the above example I used a list, but you could also use any other mutable container, or any object with mutable attributes. For example, you could make generator itself an object with last as one of its attributes:

class Generator:
    def __init__(self):
        self.last = 0.0

    def on_message(self, wsapp, message):
        data = float(message)
        if data != self.last:
            print(data)
            self.last = data

    def run_forever(self):
        websocket.WebsocketApp(
            "wss://example.websocket.test",
            on_message=self.on_message
        ).run_forever()


Generator().run_forever()

CodePudding user response:

You can use nonlocal to have the variable inside generator and be able to assign to it.

def generator:
    endpoint = "wss://example.websocket.test"
    last = 0.0
    def on_message(self, message):
        data = float(message)
        nonlocal last
        if data != last:
            print(data)
            last = data
    ws = websocket.WebsocketApp(endpoint, on_message = on_message)
    ws.run_forever()
  • Related