Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python: Persistent variable in a module without a class?

Tags:

python

module

EDIT: Here is the actual code I tried that failed:

sounds.py

import audio
import time

localAudioPlayer = None

def Play(soundString, wait=True):
    if (localAudioPlayer != None): 
        localAudioPlayer.stop()
    localAudioPlayer = audio.stream("sound/%s.ogg" % soundString)
    localAudioPlayer.play()
    if (wait == True):
        while (localAudioPlayer.playing == True):
            time.sleep(0.1)
    return

"audio" is a complete library I wrote (in a folder with an init) that allows audio playback.

The idea here is that if Play() is called while a sound is already playing, that sound should be stopped.

I don't have my code setup in such a way that I can instantiate the audio.stream() object without having an actual file to play, so pre-initializing it isn't really a good idea.

I tried similar code with my original example (I set stuffLocalVar = None then tested it for None in the function) and it worked fine. So it is something specific to this particular code.

When I did "import sounds" at the Python console and tried to execute Play() directly, I got the same traceback.

Traceback:

>>> sounds2.Play("file.ogg")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "sounds2.py", line 7, in Play
    if (localAudioPlayer != None): 
UnboundLocalError: local variable 'localAudioPlayer' referenced before assignment

Original

I'm not sure of the proper terminology for this setup, so let me give you a short example:

mainApp.py:

import stuff
print stuff.do() # should print 16
stuff.stuffLocalVar = 8
print stuff.do() # should print 32

stuff.py

stuffLocalVar = 4
def do():
    return stuffLocalVar * 4

Is this possible to do? I want to do this because the stuff.py (this is hugely simplified just to emphasize the point of the question) contains code that I don't want the user to be able to instantiate multiple classes of. There needs to be only one "instance" of this code, app-wide. But the functions in stuff.py depend on data retained within that section of code.

like image 717
fdmillion Avatar asked Sep 01 '25 17:09

fdmillion


2 Answers

Yes it is possible. You just did it.

--

Re your update: This is a completely different question, showing completely different code.

The problem with your code is that you have two different variables:

outervar = None # this is global

def foo():
    if(outervar): #this refers to the local variable
       outervar = "you fail it" # this creates a local variable

What you want is:

outervar = None # this is global

def foo():
    global outervar # prevents creation of local variable called outervar
    if(outervar):
       outervar = "you win it" # this assigns to global variable
like image 112
Marcin Avatar answered Sep 04 '25 09:09

Marcin


This is how I like to mimic a persistent/static variable in a python function without a class. This is a simple example to demonstrate. In this case the "static" variable "islicensed.value" is used to ensure that we only read the registry once, no matter how many times we call the function islicensed(). I prefer to avoid using global variables and this seems slightly more pythonic.

def islicensed(): 

    try:  # trick to mimic a persistent/static variable so I don't have to read the registry but once
        return islicensed.value
    except AttributeError:
        # read registry for license values
        settings = QtCore.QSettings("company", "myapp")
        license = str(settings.value("license"))

        if license == "somevalue":
            islicensed.value = True
        else:
            islicensed.value = False

        return islicensed.value
like image 30
panofish Avatar answered Sep 04 '25 10:09

panofish