Passing a callable object to Thread

S

skawaii

I'm trying to execute a function in its own thread, due to this method
taking a very long time to complete. I really don't see the need to
inherit the Thread class, as basically every online example shows (at
least the ones I found), nor do I want to. I want to pass the method
into the Thread constructor and let it go wild.

The function I'm trying to execute is in a modulate called tribalwars
and has the following signature:

def populate_all_tribes(data_dir)

Below is the error I'm getting after initializing the thread:
Exception in thread Thread-1:
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/2.5/lib/
python2.5/threading.py", line 462, in __bootstrap
self.run()
File "/Library/Frameworks/Python.framework/Versions/2.5/lib/
python2.5/threading.py", line 442, in run
self.__target(*self.__args, **self.__kwargs)
TypeError: populate_all_tribes() takes exactly 1 argument (8 given)

Can anybody clue me in on what I'm doing wrong? Does my function need
to have a different signature (i.e. *args, **kwargs) in order for this
to work?

Thanks,
skawaii
 
P

Paul Rubin

skawaii said:
TypeError: populate_all_tribes() takes exactly 1 argument (8 given)

Can anybody clue me in on what I'm doing wrong? Does my function need
to have a different signature (i.e. *args, **kwargs) in order for this
to work?

Thread expects args to be a tuple or list or arguments. You passed it
a list of 8 characters (what we sometimes call a string). You wanted
a tuple containing that list:

t = th.Thread(target=tribalwars.populate_all_tribes, args=("data/w7/",))
 
S

skawaii

t = th.Thread(target=tribalwars.populate_all_tribes, args=("data/w7/",))

Thanks, that did it. After playing around in the interpreter a bit, I
realize now that args=("data/w7/") doesn't create a tuple, like I
thought it would. I have to say, though, having to add a comma at the
end is hideous syntax....
 
S

Steve Holden

skawaii said:
Thanks, that did it. After playing around in the interpreter a bit, I
realize now that args=("data/w7/") doesn't create a tuple, like I
thought it would. I have to say, though, having to add a comma at the
end is hideous syntax....

Assuming you're right, what alternative would you suggest? Would it
allow parenthesized expressions to retain their customary meaning?

regards
Steve
 
B

Benjamin

Thanks, that did it. After playing around in the interpreter a bit, I
realize now that args=("data/w7/") doesn't create a tuple, like I
thought it would. I have to say, though, having to add a comma at the
end is hideous syntax....

You could type args=tuple("data/w7/").
 
P

Paul Rubin

Steve Holden said:
Assuming you're right, what alternative would you suggest? Would it
allow parenthesized expressions to retain their customary meaning?

It is kind of weird that there is even such a thing as a 1-tuple.
 
S

Steve Holden

Paul said:
It is kind of weird that there is even such a thing as a 1-tuple.

I agree that zero-length and singleton tuples don't make a great deal of
sense semantically. But by now there's been enough tuple-abuse that the
general wish is to have tuples behave exactly like lists.

Of course the singleton tuple was more or less bound to exist once the
DB API started returning result rows as tuples, and I suspect that them
empty tuple is an acceptable generalization.

regards
Steve
 
J

Jeff Schwab

Steve said:
I agree that zero-length and singleton tuples don't make a great deal of
sense semantically.

Why not? They seem intuitive to me. I would find it weird if you
couldn't have 0-tuple, and even weirder if you couldn't have a 1-tuple.
Maybe my brain has been warped by too much C++ code.

In C++, it's very common to define data structures that have no members;
the moral equivalent of an empty tuple:

struct S { };

I recently did this in C, and was surprised to see this message from gcc:

main.c:1: warning: struct has no members

It's also common in C++ to treat a stand-alone object as an array of
length 1. This is useful because any function defined to take a
sequence of input can easily be given a single element instead:

int proto = 5;
std::vector<int> v(&proto, &proto + 1);

It strikes me that 1-tuples could serve the same purpose. It's common
now for functions to be defined to take single elements, with client
code using loops to process sequences:

for item in sequence:
process(item)

If functions were instead defined to take sequences, then client code
would be simplified, especially for common tasks like processing lines
of input.

process(sequence)

On occasions when only a single item were to be processed, a 1-tuple
would serve as a nice syntactic adapter:

process((item,))
 
P

Paul Rubin

Jeff Schwab said:
Why not? They seem intuitive to me. I would find it weird if you
couldn't have 0-tuple, and even weirder if you couldn't have a
1-tuple. Maybe my brain has been warped by too much C++ code.

The idea is that a 2-tuple (of numbers, say) is a pair of numbers, a
3-tuple is three numbers, and a 1-tuple is one number. That would
mean a number and a 1-tuple of numbers are the same thing, not
separate types. This is how most type systems treat tuples.

Python does it a bit differently, treating tuples as something like
frozen lists, so they support subscripting, iterator interfaces and so
forth. There are practical advantages to doing it that way, but it
also leads to corners of oddness like the (a,) notation.
 
J

Jeff Schwab

Paul said:
The idea is that a 2-tuple (of numbers, say) is a pair of numbers, a
3-tuple is three numbers, and a 1-tuple is one number. That would
mean a number and a 1-tuple of numbers are the same thing, not
separate types.

No, that doesn't follow. A set with one element is not the same thing
as that element, a sequence of one element is not the same thing as that
element, and a tuple with one element is not the same thing as that element.
This is how most type systems treat tuples.

I take it you have particular systems in mind, but I've never used a
programming language that works that way.
Python does it a bit differently, treating tuples as something like
frozen lists, so they support subscripting, iterator interfaces and so
forth. There are practical advantages to doing it that way, but it
also leads to corners of oddness like the (a,) notation.

That "oddness" has nothing to do with tuples-of-one being strange, nor
does it imply that tuples are fundamentally different from other
collection types. It is a historical accident of the fact that
parentheses were already used to represent grouping for precedence by
the time they were overloaded to represent tuples. If bare-paren tuples
had not been allowed (as bare sets are not allowed), then there would be
no ambiguity, and no need for the (a,) notation.
 
P

Paul Rubin

Jeff Schwab said:
No, that doesn't follow.

It doesn't follow in the sense of being an unavoidable consequence
of something, it's just a plausible interpretation which is in fact
widely used.
I take it you have particular systems in mind, but I've never used a
programming language that works that way.

Basically the entire class of typed functional languages, I believe.
That "oddness" has nothing to do with tuples-of-one being strange, nor
does it imply that tuples are fundamentally different from other
collection types.

The oddness is that most other languages (at least those that I know
of) that have tuples, treat them as product types and not as
collection types.
 
L

Lie

No, that doesn't follow. A set with one element is not the same thing
as that element, a sequence of one element is not the same thing as that
element, and a tuple with one element is not the same thing as that element.

Probably the analogue of tuples in human language would be like this:
A: What ice-cream flavour do you have?
B: "Vanilla", "Chocolate", and "Strawberry"

If, for example, he only have Vanilla:
A: What ice-cream flavour do you have?
B: "Vanilla"

This way of thinking makes 1-tuple the same as the element itself.
 
J

Jeff Schwab

Lie said:
Probably the analogue of tuples in human language would be like this:
A: What ice-cream flavour do you have?
B: "Vanilla", "Chocolate", and "Strawberry"

If, for example, he only have Vanilla:
A: What ice-cream flavour do you have?
B: "Vanilla"

This way of thinking makes 1-tuple the same as the element itself.

Yes. I first heard the term "tuple" in a physics class, where it was
used to mean that a mathematical function took an arbitrary number of
objects. It was by analog with "triple, quadruple, quintuple...
n-tuple." That's a different context than computer science, though,
which is a specific branch of mathematics with its own terminology. In
CS, a tuple is a kind of data structure that is specifically not
identical with any of its elements. That's the sort of tuple used in
Python.
 
C

castironpi

Probably the analogue of tuples in human language would be like this:
A: What ice-cream flavour do you have?
B: "Vanilla", "Chocolate", and "Strawberry"
If, for example, he only have Vanilla:
A: What ice-cream flavour do you have?
B: "Vanilla"
This way of thinking makes 1-tuple the same as the element itself.

Yes.  I first heard the term "tuple" in a physics class, where it was
used to mean that a mathematical function took an arbitrary number of
objects.  It was by analog with "triple, quadruple, quintuple...
n-tuple."  That's a different context than computer science, though,
which is a specific branch of mathematics with its own terminology.  In
CS, a tuple is a kind of data structure that is specifically not
identical with any of its elements.  That's the sort of tuple used in
Python.- Hide quoted text -
a= object()
(a,) is a False
(a,) is (a,) False
a is a True
(a,) == (a,) True
a= []
a.append( a )
a [[...]]
tuple(a) is tuple(a)
False

hasVanilla= True
hasStrawberry= True
hasChocolate= True
if hasVanilla:
print "Vanilla"
if hasVanilla and not hasChocolate:
print "and"
if hasStrawberry:
print "Strawberry"
if hasVanilla or hasStrawberry and hasChocolate:
print "and"
if hasChocolate:
print "Chocolate."
 
J

Jeff Schwab


(a,) is not identical with a.

The tuple on the left is not identical with the tuple on the right, even
though they are equivalent.

The variable on the left is identical with the one on the right. This
is not the same comparison as "(a,) is (a,)", which actually contains
the construction of two distinct objects. The moral equivalent of "a is
a" would be:
True

An interesting thing about Python is that numbers of built-in types are
flyweights. Unlike literals of non-flyweight types, distinct instances
of a given numeric literal actually refer to the same object:
True

I wonder, will this be true of the upcoming Fraction class?

The two tuples are equivalent (though not identical).

That's cool. I don't think would have known off the top of my head how
the interactive interpreter would display something like that. Talk
about a cyclic reference...

The tuple on the left is not identical with the tuple on the right, even
though they are equivalent. This is the sample as one of your earlier
examples, just with slightly different syntax.
hasVanilla= True
hasStrawberry= True
hasChocolate= True
if hasVanilla:
print "Vanilla"
if hasVanilla and not hasChocolate:
print "and"
if hasStrawberry:
print "Strawberry"
if hasVanilla or hasStrawberry and hasChocolate:
print "and"
if hasChocolate:
print "Chocolate."

You've tried to implement a set using a set of flags to indicate whether
various items have membership in that set. See how an object
representing a given flavor would have to be distinct from the object
(boolean flag) indicating its set membership? Btw, your formatting
could use some work. :) Some flavor combinations cause extra "ands" to
be printed. Here's a little test harness, with PEP-friendly variable
names, and showing how your booleans corresponding directly with
traditional bit-bucket flag sets:

def print_flavors(flags):

print flags

vanilla = flags & 1
strawberry = flags & 2
chocolate = flags & 4

if vanilla:
print "Vanilla"
if vanilla and not chocolate:
print "and"
if strawberry:
print "Strawberry"
if vanilla or strawberry and chocolate:
print "and"
if chocolate:
print "Chocolate."

if __name__ == '__main__':
for flavor_flags in range(8):
print_flavors(flavor_flags)
 
P

Paul Rubin

The usual CS meaning of "tuple" is more like the physics meaning than
like the Python meaning, I think.
The tuple on the left is not identical with the tuple on the right,
even though they are equivalent.

Implementation artifact. It could be constant folded.
x = (a,)
y = x
x is y
should print True.
An interesting thing about Python is that numbers of built-in types
are flyweights. Unlike literals of non-flyweight types, distinct
instances of a given numeric literal actually refer to the same object:

True

Again an implementation artifact, not guaranteed by the language. Try:
(5+1) is (5+1)
then try
(999999999999999999999999999999+1) is (999999999999999999999999999999+1)
 
J

Jeff Schwab

Paul said:
The usual CS meaning of "tuple" is more like the physics meaning than
like the Python meaning, I think.

That has not been my experience.
Implementation artifact. It could be constant folded.
x = (a,)
y = x
x is y
should print True.

I gave a similar example, but you snipped it.
Again an implementation artifact, not guaranteed by the language. Try:
(5+1) is (5+1)
True

then try
(999999999999999999999999999999+1) is (999999999999999999999999999999+1)

False

I think you're a little confused about the meaning of "numeric literal."
(5+1) is not a numeric literal. Neither is
(999999999999999999999999999999+1).

The flyweight pattern does not guarantee that all equivalent instances
of an object type will be identical. Maybe I should have said that
*some* distinct instances of a given numeric literal actually refer to
the same object, so as not to imply that *all* of them did. I don't
know whether 5 is always guaranteed to be the same object as any other 5
in a given Python session.
 
P

Paul Rubin

Jeff Schwab said:
I think you're a little confused about the meaning of "numeric
literal." (5+1) is not a numeric literal. Neither is
(999999999999999999999999999999+1).

The flyweight pattern does not guarantee that all equivalent instances
of an object type will be identical.

I don't think there's any Python language rule that says multiple uses
of the same numeric literal turn into the same object. It's just an
optimization (constant folding) that the CPython implementation
happens to perform. Other implementations might not do it, or CPython
might do it differently in some future version.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,994
Messages
2,570,222
Members
46,810
Latest member
Kassie0918

Latest Threads

Top