2

I have a python program that has several classes that when called invoke additional threads. These threads each call a separate python script to do stuff.

I followed the recommendations suggested in the question posted on "Python threading inside a class" and created the class to call the separate threads.

Below is a sample snippet of what I have.

class SomeThread(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)

    def run(self):
        os.system('start Python_program_to_do_stuff.py')

I then instantiate several versions of this thread like this:

Some_Thread_1 = SomeThread()
Some_Thread_2 = SomeThread()
...

I set them to True

Some_Thread_1.setDaemon(True)
Some_Thread_2.setDaemon(True)

And then when actually invoking, I call each one independently

Some_Thread_1.start()

This opens a separate window to run 'Python_program_to_do_stuff.py'. Output from this program is stored at a predetermined location hard coded inside of it.

The current python program works well, but now I want to pass a very specific parameter to the class every time that it is invoked so the output data is stored in a specific location for that call. So for example, the first time I call class 'SomeThread' (ie executing Some_Thread_1.start()), store the output at location A, second time store at location B, etc. This location is not fixed and it depends on the test that I am running.

I imagine, following the reference above, that I could do something like this:

class SomeThread(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)

    def run(self, path_for_output_data):
        self.path_for_output_data = path_for_output_data
        os.system('start Python_program_to_do_stuff.py', path_for_output_data)

and then when invoking:

Some_Thread_1.start("c:/data")

but I am getting an error: "start() takes exactly 1 argument (2 given) ".

Tips are appreciated.

{As as side note, I am exploring the use of subprocess.Popen() instead of os.system(), but that is a separate mess).

2 Answers 2

1

If possible you could pass the path as you instantiate each thread:

class SomeThread(threading.Thread):
    def __init__(self, path_for_output_data):
        threading.Thread.__init__(self)
        self.path_for_output_data = path_for_output_data

    def run(self):
        os.system('start Python_program_to_do_stuff.py', self.path_for_output_data)

Some_Thread_1 = SomeThread("c:/data")

Some_Thread_1.start()
Sign up to request clarification or add additional context in comments.

2 Comments

correct me if I'm wrong but does os.system not fail with 2 arguments? I believe what you're doing is closest to passing arguments in an iterable to subprocess.call
No, I didn't see that you did this. After I did though, I realized you're passing more than 1 argument to os.system and left mine up because I'd already come up with a working example. Not sure what you're getting at here. If you're worried about your solution not getting the checkmark, OP can always read this thread and decide accordingly. You did include that idea before me, per the timestamps, I'll grant you that. I included the "can't do os.system(x, y)" comment because I copy-pasted OP's example into my editor for testing it and realized that.
1

That's because Thread.start takes only 1 argument. Read on it here: https://docs.python.org/3/library/threading.html#thread-objects

The method declaration does not take any additional arguments

Implementation

If you would like to pass arguments to a target invocation, you may use the args or kwargs parameter.

You may also modify SomeThread to take your path as an argument, that you can then call your file with:

class SomeThread(threading.Thread):
    def __init__(self, path_for_output_data):
        threading.Thread.__init__(self)
        self.path_for_output_data = path_for_output_data

    def run(self):
        # cannot do os.system(x, y) as it only takes 1 argument
        os.system('Python_program_to_do_stuff.py '+self.path_for_output_data)

# pass the path to it, and when run is called that path should be passed as a command-line argument to your file
SomeThread("c:/data").start()

1 Comment

Elegant. It worked rather well.

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.