Python Threading question

lme@

Administrator
Staff member
Administrator
Moderator
Developer
Not a specific FreeBSD question, but let's see what the people around here know about Python. ;)

I'd like to do some threaded ssh connections with threading.Thread() and system.
To do that I wrote a function1 which connects to one host via ssh and a function2 which loops through a list of hosts and starts a thread with function1 and one host at a time as the function1's argument.
Here is where the fun comes in:
Not the hostname is given as an argument but every single character of it. So I am getting the error message that there are 8 arguments passed on to function1 instead of 1.

You can find the code snippet and the error message here:

http://bsdpaste.bsdgroup.de/1016


Any ideas anyone?
 
With "" it doesn't work either.
The funny thing is that when I extend check_zip_comp(host) to check_zip_comp(foo, host) and pass args=(foo, hosts) then it works and the host is parsed correctly.
 
Okay, here it is, just c&p and run it:

Code:
#!/usr/bin/env python

import os
import sys
from threading import Thread

HOSTS = ('FOOBAR', 'BLAH')

def my_func(host):
	print host
	return

my_threads = []
for host in HOSTS:
	t = Thread(target=my_func, args=host)
	my_threads.append(t)
	t.start()
for thread in my_threads:
    thread.join()

sys.exit(0)

With syntax highlighting: http://bsdpaste.bsdgroup.de/1017
 
Im not very good in Python, but with little searching in documentation you could make smth liek :
Code:
my_threads = []
for host in HOSTS:
	t = Thread(target=my_func, args=[B](host,)[/B])
	my_threads.append(t)
	t.start()

This is because of :
class threading.Thread(group=None, target=None, name=None, args=(), kwargs={})

This constructor should always be called with keyword arguments. Arguments are:

group should be None; reserved for future extension when a ThreadGroup class is implemented.

target is the callable object to be invoked by the run() method. Defaults to None, meaning nothing is called.

name is the thread name. By default, a unique name is constructed of the form “Thread-N” where N is a small decimal number.

args is the argument tuple for the target invocation. Defaults to ().

and the (host,) create one element tuple.
 
tyson said:
Im not very good in Python, but with little searching in documentation you could make smth liek :
Code:
my_threads = []
for host in HOSTS:
	t = Thread(target=my_func, args=[B](host,)[/B])
	my_threads.append(t)
	t.start()

This is because of :


and the (host,) create one element tuple.

Thanks a lot for the explanation! It's working now. Now I even managed to get it working with args=[host].

Python is a little strange. ;)
 
lme@ said:
Thanks a lot for the explanation! It's working now. Now I even managed to get it working with args=[host].

Python is a little strange. ;)

I believe this is because [] is syntax for a list and a tuple () is an immutable list.
 
Basically, it expects something subscriptable with a length, and a string qualifies even though that's not quite what you meant.

In python, strings implement __getitem__, __getslice__, __setitem__, __setslice__, __len__ and __iter__, so you can treat them like a list. A side effect is that when you pass a string to something that expects a tuple or list of strings, it acts just like if you passed a list of strings of length 1. Which is why you need to construct a one-element tuple or list with the string in it when passing it to a method like this.

It's perhaps a bit odd, but it makes sense. :)
(It's also an example of duck typing in action: The argument is supposed to be a list; so try using whatever we got as one. If that works, fine.)
 
Back
Top