Python Threading - Creation of a subclass? - python

I am having a problem wrapping my brain around the reason for creating a subclass when using threading in python. I've read a number of websites including tutorialspoint.
The docs say you need to define a new subclass of the Thread class. I have a basic understanding of classes but haven't played with subclasses at all. I haven't had to do anything like this yet with any other modules I've used like os & ftplib. Can anyone point me to a site that may explain this better for a newbie scripter?
#!/usr/bin/python
import threading
class myThread (threading.Thread):
I was able to write my own script without creating this subclass and it works so I am not sure why this is stated as a requirement. This is my simple little script I created to help me understand threading initially.
#!/usr/bin/python
# Import the necessary modules
import threading
import ftplib
# FTP function - Connects and performs directory listing
class
def ftpconnect(target):
ftp = ftplib.FTP(target)
ftp.login()
print "File list from: %s" % target
files = ftp.dir()
print files
# Main function - Iterates through a lists of FTP sites creating theads
def main():
sites = ["ftp.openbsd.org","ftp.ucsb.edu","ubuntu.osuosl.org"]
for i in sites:
myThread = threading.Thread(target=ftpconnect(i))
myThread.start()
print "The thread's ID is : " + str(myThread.ident)
if (__name__ == "__main__"):
main()
Thanks for the help!
I am using tutorialspoint.com for my reference material. It sounds like your saying I am biting off more than I can chew and I should keep it simple at this point considering I don't need to use the more complicated options yet. This is what the site says:
Creating Thread using Threading Module:
To implement a new thread using the threading module, you have to do the following:
- Define a new subclass of the Thread class.
- Override the __init__(self [,args]) method to add additional arguments.
- Then, override the run(self [,args]) method to implement what the thread should do when started.
Once you have created the new Thread subclass, you can create an instance of it and then start a new thread by invoking the start(), which will in turn call run() method.

The docs say you need to define a new subclass of the Thread class.
and
I was able to write my own script without creating this subclass and it works so I am not sure why this is stated as a requirement.
The Python docs say no such thing, and can't guess which docs you're talking about. Here are Python docs:
There are two ways to specify the activity: by passing a callable object to the constructor, or by overriding the run() method in a subclass. No other methods (except for the constructor) should be overridden in a subclass. In other words, only override the init() and run() methods of this class.
You're using the first method specified there (passing a callable to the Thread() constructor). That's fine. Subclasses become more valuable when the callable needs access to state variables and you don't want to clutter your program with globals for that purpose, and especially when using multiple threads that each need their own state variables. Then state variables can usually be implemented as instance variables on your own subclass of threading.Thread. If you don't need that (yet), don't worry about it (yet).

Related

Python: What are the dangers of passing a specific object's function as an argument

In the main code, I have an instance of a class called "debugPrinterObject".
After instantiating it, I pass one of it's functions as an argument to another class called "bSoupProcessor" which processes text. Any logging information is saved to a text file using the function passed into the constructor of the bSoupProcessor class.
This is done so that the file is held open by the debugPrinterObject, and editable through the function passed as an argument. the text file is only closed at the end of the program.
It is working so far. I am going to implement multi threading, where there will be multiple "bSoupProcessor" classes, and they will all be using the same function of the "debugPrinterObject". Is this possible? are there any problems/risks?
The only dangers are the typical concurrency issues you'd face in this situation. Be sure to either use Lock objects inside your logging method, or use them in bSoupProcessor before calling it.

Is declaring function within function for threading good programming style?

I have following code for click handler in my PyQT4 program:
def click_btn_get_info(self):
task = self.window.le_task.text()
self.statusBar().showMessage('Getting task info...')
def thread_routine(task_id):
order = self.ae.get_task_info(task_id)
if order:
info_str = "Customer: {email}\nTitle: {title}".format(**order)
self.window.lbl_order_info.setText(info_str)
self.statusBar().showMessage('Done')
else:
self.statusBar().showMessage('Authentication: failed!')
thread = threading.Thread(target=thread_routine, args=(task,))
thread.start()
Is it a good practice to declare function in function for using with threads?
In general, yes, this is perfectly reasonable. However, the alternative of creating a separate method (or, for top-level code, a separate function) is also perfectly reasonable. And so is creating a Thread subclass. So, there's no rule saying to always do one of the three; there are different cases where each one seems more reasonable than the others, but there's overlap between those cases, so it's usually a judgment call.
As Maxime pointed out, you probably want to use Qt's threading, not native Python threading. Especially since you want to call methods on your GUI objects. The Qt docs article Threads, Events and QObjects in the Qt documentation gives you an overview (although from a C++, not Python, viewpoint). And if you're using a QThread rather than a threading.Thread, it is much more common to use the OO method—define a subclass of QThread and override its run method than to define a function, which makes your question moot.
But if you do stick with Python threading, here's how I'd decide.
Pro separate method:
You're doing this in a class method, rather than a function, and that the only state you want to share with the new thread is self.
Non-trivial code, longer than the function it's embedded in.
Pro local function:
Pretty specific to the info button callback; no one else will ever want to call it.
I'd probably make it a method, but I wouldn't complain about someone else's code that made it a local function.
In a different case—e.g., if the thread needed access to a local variable that had no business being part of the object, or if it were a trivial function I could write as an inline lambda, or if this were a top-level function sharing globals rather than a method sharing self, I'd go the other direction.

Why does an imported python module stop working once multiprocessing has begun?

I have a class in which I import a module (call it myModule). Among other things, I use this module for an object it provides:
myObject = myModule.ImportantObject()
This object worked fine whenever I used it in the class, until I started using multiprocessing. In particular, my class has a method called go(), which creates two multiprocessing Processes (whose targets are other methods of this class), and then starts them. The strange thing is that once these Processes are started, all calls relating to myObject fail, and I further discovered that it becomes impossible to create a new myModule.ImportantObject(). These failed calls are being made from the target methods of the Processes, and from other methods that they themselves call.
The final interesting part is that myObject continues to work fine from within the go() method (where the multiprocessing was started), but no where else.
Any ideas?
*EDIT: myModule is a music-related module trying to send MIDI messages through a virtual port via CoreAudio.

Is there a problem with inheriting from threading.Thread without actually starting the thread?

I've created a Python class which inherits from threading.Thread, instances of which may not actually be run as a new thread (because the start() method is never invoked). The code has been written such that it works whether start() has been invoked or not (just in a slightly different way). This is entirely intentional.
Is there a problem or overhead with not ever invoking the start() method on an instance of the class? Is there a better way to write a class that is sometimes run in a new thread and sometimes not?
Inheriting from Thread insists on appending a Thread-n to the repr() string on the class instance, even if it isn't running.
In my view a slightly cleaner design would be to not inherit your class from threading.Thread, but keep its run method as-is.
Now:
if you don't need threading, you can continue to use your class as you do currently;
if you do need threading, create a new Thread object, setting the target= constructor argument to your object's run method.

About the need of creating a class in Python

Let's say that i have a Python module to control a videoconference system. In that module i have some global variables and functions to control the states of the videoconference, the calls, a phone book, etc.
To start the control system, the module self-executes a function to initialize the videoconference (ethernet connection, polling states and so)
Now, if i need to start controlling a second videoconference system, i'm not sure how to approach that problem: i thought about making the videoconference module a class and create two instances (one for each videoconference system) and then initialize both, but the problem is that i don't really need to have two instances of a videoconference class since i won't do anything with those objects because i only need to initialize the systems; after that i don't need to call or keep them for anything else.
example code:
Videoconference.py
class Videoconference:
def __init__(self):
self.state = 0
#Initialization code
Main.py
from Videoconference import Videoconference
vidC1 = Videoconference()
vidC2 = Videoconference()
#vidC1 and vidC2 will never be use again
So, the question is: should i convert the videoconference module to a class and create instances (like in the example), even if i'm not going to use them for anything else appart of the initialization process? Or is there another solution without creating a class?
Perhaps this is a matter of preference, but I think having a class in the above case would be the safer bet. Often I'll write a function and when it gets too complicated I'll think that I should have created a class (and often do so), but I've never created a class that was too simple and thought that this is too easy why didn't I just create a function.
Even if you have one object instead of two, it often helps readability to create a class. For example:
vid = VideoConference()
# vid.initialize_old_system() # Suppose you have an old system that you no longer use
# But want to keep its method for reference
vid.initialize_new_system()
vid.view_call_history(since=yesterday)
This sounds like the perfect use case for a VideoConferenceSystem object. You say you have globals (ew!) that govern state (yuck!) and calls functions for control.
Sounds to me like you've got the chance to convert that all to an object that has attributes that hold state and methods to mutate it. Sounds like you should be refactoring more than just the initialization code, so those vidC1 and vidC2 objects are useful.
I think you're approaching this problem the right way in your example. In this way, you can have multiple video conferences, each of which may have different attribute states (e.g. vidC1.conference_duration, etc.).

Categories

Resources