简体   繁体   中英

Python Class passing value to “self”

I'm programming an optimizer that has to run through several possible variations. The team wants to implement multithreading to get through those variants faster. This means I've had to put all my functions inside a thread-class. My problem is with my call of the wrapper function

class variant_thread(threading.Thread):
    def __init__(self, name, variant, frequencies, fit_vals):
        threading.Thread.__init__(self)
        self.name = name
        self.elementCount = variant
        self.frequencies = frequencies
        self.fit_vals = fit_vals
    
    def run(self):
        print("Running Variant:", self.elementCount) # display thread currently running
        fitFunction = self.Wrapper_Function(self.elementCount)
    
        self.popt, pcov, self.infoRes = curve_fit_my(fitFunction, self.frequencies, self.fit_vals)

    def Optimize_Wrapper(self, frequencies, *params): # wrapper which returns values in manner which optimizer can work with
        cut = int(len(frequencies)/2) <---- ERROR OCCURS HERE
        freq = frequencies[:cut]
        vals = (stuff happens here)
        return (stuff in proper form for optimizer)

I've cut out as much as I could to simplify the example, and I hope you can understand what's going on. Essentially, after the thread is created it calls the optimizer. The optimizer sends the list of frequencies and the parameters it wants to change to the Optimize_Wrapper function.

The problem is that Optimize-Wrapper takes the frequencies-list and saves them to "self". This means that the "frequencies" variable becomes a single float value, as opposed to the list of floats it should be. Of course this throws an errorswhen I try to take len(frequencies). Keep in mind I also need to use self later in the function, so I can't just create a static method.

I've never had the problem that a class method saved any values to "self". I know it has to be declared explicitly in Python, but anything I've ever passed to the class method always skips "self" and saves to my declared variables. What's going on here?

Don't pass instance variables to methods. They are already accessible through self . And be careful about which variable is which. The first parameter to Wrapper_function is called "frequency", but you call it as self.Wrapper_Function(self.elementCount) - so you have a self.frequency and a frequency ... and they are different things. Very confusing!

class variant_thread(threading.Thread):
    def __init__(self, name, variant, frequencies, fit_vals):
        threading.Thread.__init__(self)
        self.name = name
        self.elementCount = variant
        self.frequencies = frequencies
        self.fit_vals = fit_vals
    
    def run(self):
        print("Running Variant:", self.elementCount) # display thread currently running
        fitFunction = self.Wrapper_Function()
        self.popt, pcov, self.infoRes = curve_fit_my(fitFunction, self.frequencies, self.fit_vals)

    def Optimize_Wrapper(self): # wrapper which returns values in manner which optimizer can work with
        cut = int(len(self.frequencies)/2) <---- ERROR OCCURS HERE
        freq = self.frequencies[:cut]
        vals = (stuff happens here)
        return (stuff in proper form for optimizer)

You don't have to subclass Thread to run a thread. Its frequently easier to define a function and have Thread call that function. In your case, you may be able to put the variant processing in a function and use a thread pool to run them. This would save all the tedious handling of the thread object itself.

def run_variant(name, variant, frequencies, fit_vals):
    cut = int(len(self.frequencies)/2) <---- ERROR OCCURS HERE
    freq = self.frequencies[:cut]
    vals = (stuff happens here)
    proper_form = (stuff in proper form for optimizer)
    return curve_fit_my(fitFunction, self.frequencies, self.fit_vals)

if __name__ == "__main__":
    variants = (make the variants)
    name = "name"
    frequencies = (make the frequencies)
    fit_vals = (make the fit_vals)
    from multiprocessing.pool import ThreadPool
    with ThreadPool() as pool:
        for popt, pcov, infoRes in pool.starmap(run_variant,
                ((name, variant, frequencies, fit_vals) for variant in variants)):
            # do the other work here

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM