Michael Markieta
Michael Markieta

Reputation: 442

Preventing a class instance from being evaluated until it's parameters have been set

I am not 100% sure this is called lazy-evaluation or not, but I am hoping to do this in Python.

I have a "setup wizard" which a user will go through and in turn create some global variables which will be used as parameters in a class.

var = myClass(param1, param2) should not be evaluated until global variables param1 and param2 exist. However, I need var to exist because I am associating var0 = var.func, a function inside myClass. Later on in the application, var0 is called and func() is performed.

Updated

Here is a bit of my code:

class myClass:

    def __init__(self, param1, param2):
        self.param1 = param1
        self.param2 = param2
    #------------------------------------------------------------------------
    def myFunction(self):
        """
        Some work here using self.param1 and self.param2
        """
    def myFunction2(self):
        """
        Some work here using self.param1 and self.param2
        """
    def myFunction3(self):
        """
        Some work here using self.param1 and self.param2
        """

myInstance = myClass(PARAM1, PARAM2)

myDict = {}
myDict["key1"] = myInstance.myFunction
myDict["key2"] = myInstance.myFunction2
myDict["key3"] = myInstance.myFunction3
# and so on...

PARAM1 and PARAM2 are populated as global variables by the user through actions inside of a wxPython wizard. The problem is that myInstance cannot be evaluated at initialization because PARAM1 and PARAM2 don't exist yet. However, the dictionary key's are being associated to the various functions at initialization because they won't change over time.

Ideas?

Upvotes: 0

Views: 359

Answers (4)

Michael Markieta
Michael Markieta

Reputation: 442

I used the @staticmethod decorator to get past this in my code, but I won't accept it as an answer as I don't know if this is the best answer at the moment!!

class myClass:
    #------------------------------------------------------------------------
    @staticmethod
    def myFunction(param1, param2):
        """
        Some work here using param1 and param2
        """
    @staticmethod
    def myFunction2(param1, param2):
        """
        Some work here using param1 and param2
        """
    @staticmethod
    def myFunction3(param1, param2):
        """
        Some work here using param1 and param2
        """

myDict = {}
myDict["key1"] = myClass.myFunction
myDict["key2"] = myClass.myFunction2
myDict["key3"] = myClass.myFunction3
# and so on...

and after the user passes through the setup wizard and populated PARAM1 and PARAM2, I can loop through the dictionary and calculate the respective value pair using its associated function by passing PARAM1 and PARAM2 like so:

for k in myDict.keys():
    myDict[k](PARAM1, PARAM2)

Upvotes: 0

Hugh Bothwell
Hugh Bothwell

Reputation: 56654

Instead of

var = MyClass(p1, p2)

p1 = get_p1()
p2 = get_p2()

# magic happens

why not

var = MyClass()

p1 = get_p1()
var.p1 = p1

p2 = get_p2()
var.p2 = p2

Upvotes: 0

mgilson
mgilson

Reputation: 310019

THIS IS A BAD IDEA

But, here's some code which will do what you want I think...

class myClass(object):
    @property
    def var0(self):
        return param1

a=myClass()
try:
    print (a.var0) #NameError because param1 isn't defined yet.
except NameError:
    pass

param1="foo"   
print a.var0

We can make this even more "clever" (see below) -- Now you just have to pass a string which contains the name of the variable that will be created at some point.

class myClass(object):
    def __init__(self,varname):
        self.varname=varname
    @property
    def var0(self):
        return globals()[self.varname]

a=myClass('param1')
try:
    print (a.var0) #KeyError now
except KeyError:
    pass

param1="foo"
print a.var0

This defers accessing the global variable param1 until it is actually used on the class. However, generally, you don't want to do this. Defer instance creation until after the variables that you are going to pass have been defined.

Upvotes: 1

Marcin
Marcin

Reputation: 49856

No, you don't want to do this.

What you should do, if you really need to do this, is to use promises or futures to delay evaluation of those expressions. This is because even if the variable var exists, the expression var.func will only evaluate without exception if var holds an object with a member func. There are a number of promise or future libraries for python - I suggest that you google them yourself, in order to choose the one that suits you best.

However, a better way to do this is simply to not perform any of these operations until the class exists, or the global variables are set.

Unfortunately, as you have provided almost no details of what you are doing, it is impossible to provide any more concrete advice.

Upvotes: 2

Related Questions