Basic Python Query

C

chandan kumar

Hi all,

Please see the below code.

class Test(threading.Thread):    
      def StartThread(self):
       Lock = threading.Lock()
        self.start()   


class Test1(threading.Thread):
    def __init__(self):
        threading.Thread.__init__ ( self )
        self.Lock = threading.Lock()
self.start()   


if __name__ == '__main__':

       instance = Test()

       instance.StartThread()


       instance1= Test1()
       instance1.start()

Please clarify the questions below with respect to above code

1.Difference between  def StartThread(self) and def __init__(self):
2   instance = Test() ,when this is called ,the code flow goes inside the threading module ,But 
      instance1= Test1() ,the code flow goes inside the class Test1
     When we call the both classes in same way ,How does the flow is different for both.
3. Lets say self is passed explicitly for all the methods Like
    def method1(self)
         method2()
   def  method2(self):
         method3()
   def method(self)
        method4()
   def method4(self)
 What does self holds in method4 ,Is it self argument from method1? Sorry i'm confused with self argument.Please clarify if its valid question.

Best Regards,
Chandan
 
S

Steven D'Aprano

On Wed, 21 Aug 2013 14:50:20 +0800, chandan kumar wrote:

[...]
1.Difference between  def StartThread(self) and def __init__(self):

__init__ is a special method called automatically by Python when you
create an instance. StartThread is a method that the author of the code
(perhaps you?) wrote themselves. It has no special meaning in Python, it
will do whatever it is programmed to do, but only if you call it.

2   instance = Test() ,when this is called ,the code flow goes inside
the threading module , But 
    instance1= Test1() ,the code flow goes inside the class Test1
     When we call the both classes in same way ,How does the flow is
different for both.


When Test() is called, a new Test instance is created, and the __init__
method is called, but the thread is not started.

When you call Test1(), the __init___ method automatically starts the
thread, because it includes the line "self.start()".

(Although, in the code you show, the indentation is wrong and the code
will not work correctly. Please be more careful in the future about the
indentation.)

3. Lets say self is passed explicitly for all the methods Like
    def method1(self)
         method2()

That won't work, you need to say self.method2()

   def  method2(self):
         method3()
   def method(self)
        method4()
   def method4(self)

 What does self holds in method4 ,Is it self argument from method1?
Sorry i'm confused with self argument.Please clarify if its valid
question.

Yes, it is the same "self" all the way through. If you have ordinary
functions:

def f1(x):
f2(x)

def f2(y):
f3(y)

def f3(z):
print z

and you call f1("something"), then the result will be to print
"something". Even though the argument name is different, the same
argument is passed from one function to the next.

Methods are exactly the same, except that the "self" argument is nearly
always called "self".

When you have an instance, and you call one of its methods:

instance = SomeClass()
instance.method(extra, args)

then Python automatically uses the instance as the "self" argument. This
is equivalent to:

SomeClass.method(instance, extra, args)
# inside the method, self=instance


except Python does it for you, instead of you needing to write it out in
full like that.
 
U

Ulrich Eckhardt

Am 21.08.2013 08:50, schrieb chandan kumar:
class Test(threading.Thread):
def StartThread(self):
Lock = threading.Lock()
self.start()

Inconsistently indented code, this is a killer for Python. Please read
PEP8 and use four spaces! That said, there is never a need for deriving
from the Thread class, you can also use it to run a function without
that. That way is IMHO clearer because the threading.Thread instance is
not the thread, just like a File instance is not a file. Both just
represent handles for manipulating the actual thing.

Further, you have a local variable called "Lock" here (should be
lowercase, see PEP 8) that you don't use. This is either a bug you
missed or at least code that you didn't trim in order to produce a
minimal example.

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

Check out the "super()" syntax.

1.Difference between def StartThread(self) and def __init__(self):

__init__ is a special function that gets called automatically. Search
online for the documentation and or further explanations.

3. Lets say self is passed explicitly for all the methods Like
def method1(self)
method2()
def method2(self):
method3()
def method(self)
method4()
def method4(self)
What does self holds in method4 ,Is it self argument from method1?
Sorry i'm confused with self argument.

"self" is just a name like others, only that it is customarily used for
the first parameter of memberfunctions, i.e. for the instance of the
according class. That said, above seven lines don't really serve to
illustrate anything, because they are far from valid Python code.

I think before tackling threading, you should first go through some
tutorials and documentation. I'd start with http://docs.python.org
and/or do some online searches.

Good luck!

Uli
 
J

Johannes Bauer

That said, there is never a need for deriving
from the Thread class, you can also use it to run a function without
that. That way is IMHO clearer because the threading.Thread instance is
not the thread, just like a File instance is not a file. Both just
represent handles for manipulating the actual thing.

Huh? That I find most curious.

I *always* derive from threading.Thread and really like the way that
thread setup works (instanciate Thread handle, call start). Very
intuitive, never had the problems with clarity that you mentioned. Could
you elaborate on your suggestion? I don't seem to quite get it I'm afraid.

Best regards,
Johannes

--
Zumindest nicht öffentlich!
Ah, der neueste und bis heute genialste Streich unsere großen
Kosmologen: Die Geheim-Vorhersage.
- Karl Kaos über Rüdiger Thomas in dsa <[email protected]>
 
F

Fábio Santos

Huh? That I find most curious.

I *always* derive from threading.Thread and really like the way that
thread setup works (instanciate Thread handle, call start). Very
intuitive, never had the problems with clarity that you mentioned. Could
you elaborate on your suggestion? I don't seem to quite get it I'm afraid.

Best regards,
Johannes

I cannot tell whether you are trolling or are just new to this, but you
don't always have to use threads. You use threads when you need multiple
parts of your program running concurrently. Don't inherit Thread if all you
are doing is a simple object with state, nor if your program does not need
concurrency.
 
N

Ned Batchelder

I cannot tell whether you are trolling or are just new to this, but
you don't always have to use threads. You use threads when you need
multiple parts of your program running concurrently. Don't inherit
Thread if all you are doing is a simple object with state, nor if your
program does not need concurrency.
I think it is safe to assume that Johannes meant, "when I use threads, I
never do it the way you suggested, I always derive from threading.Thread."

--Ned.
 
F

Fábio Santos

Hi all,

Sorry for not explaining question properly.Here Its not about threading
and dont worry about any indentations.Please see below example
class Call_Constructor():
def __init__(self):
print "In __init__ "

class Test_Constructor(Call_Constructor):
def method(self):
print " In Test_Constructor Class"

ConstructInstance = Test_Constructor()

When an instace is created for Test_Constructor class ,The code flows
starts __init__ in Call_Constructor class.Whys is it like that.
class Call_Constructor():
def __init__(self):
print "In __init__ "


class Test_Constructor(Call_Constructor):
def __init__(self):
print " In Test_Constructor Class"

ConstructInstance = Test_Constructor()

But for the above case Code flows starts from Test_Constructor().

Whats is the difference for both cases described above.

Best Regards,
Chandan.

When creating an instance, Python will call __init__. In the first example
there was only an __init__ method in the base class, so that one was used.
On the second example, there were __init__ methods on both classes, but
since you instantiated the subclass, the subclass's __init__ method was
executed.

Subclass methods have precedence over base class methods. If you want the
__init__ method of the base class in the second example to be called, you
can either remove the subclass __init__ method or call
super(TestConstructor, self).__init__() in that method. That will call the
base class's __init__.
 
J

Johannes Bauer

I cannot tell whether you are trolling or are just new to this,
Neither!

but you
don't always have to use threads.

Obviously, I meant "I always derive from threading.Thread when I need to
work with a thread". Thought this was blatantly obvious.

That said, I think I also grossly misunderstood Ulrichs posting. He was
talking about there no need deriving from threading.Thread when you
don't need threads.

What I understood was that, in order to use Threads, you could also just
pass a closure to some static function of threading in order to fire up
a thread. That may or may not be true. However, I find deriving from
Thread, instanciating an object and firing up the thread by using
".start()" much more intuitive.

Hope that clears it all up.

Best regards,
Johannes

--
Zumindest nicht öffentlich!
Ah, der neueste und bis heute genialste Streich unsere großen
Kosmologen: Die Geheim-Vorhersage.
- Karl Kaos über Rüdiger Thomas in dsa <[email protected]>
 
J

Johannes Bauer

I think it is safe to assume that Johannes meant, "when I use threads, I
never do it the way you suggested, I always derive from threading.Thread."

Yup, that's what I was aiming for.

Best regards,
Johannes

--
Zumindest nicht öffentlich!
Ah, der neueste und bis heute genialste Streich unsere großen
Kosmologen: Die Geheim-Vorhersage.
- Karl Kaos über Rüdiger Thomas in dsa <[email protected]>
 
U

Ulrich Eckhardt

Am 21.08.2013 20:58, schrieb Johannes Bauer:
Huh? That I find most curious.

I *always* derive from threading.Thread and really like the way that
thread setup works (instanciate Thread handle, call start). Very
intuitive, never had the problems with clarity that you mentioned. Could
you elaborate on your suggestion? I don't seem to quite get it I'm afraid.

What is clear, convenient or not is largely a matter of taste. I'll try
to explain my motivations though, maybe it helps...


Firstly, there is one observation: The Python object of type Thread is
one thing, the actual thread is another thing. This is similar to the
File instance and the actual file. The Python object represents the
other thing (thread or file) but it "is not" this thing. It is rather a
handle to the file or thread. This is different for e.g. a string, where
the Python object is the string.

Due to this pairing between the actual thing and the handle, there is
also some arity involved. For a single thread or file, there could be
multiple Python objects for handling it, or maybe even none. When the
Python object goes away, it doesn't necessarily affect the thread or
file it represents. This already casts a doubt on the habit of deriving
from the Thread type, just like deriving from the File type is highly
unusual, as you are just deriving from a handle class.


Secondly, a thread is even less a "thing" than a file but rather a
process or an ongoing operation. As such, it runs code and uses data but
it is neither code nor data. Also, it doesn't care which code or data it
currently uses. Similarly, the code and data don't care which thread
uses them (synchronization problems in multithreaded apps aside). You
will find that most of the code called in a thread doesn't use the
thread handle, which is another sign that it doesn't care. For that
reason, it is unnecessary that "self" references a Thread object. This
reduces coupling, as the same code could be called synchronously and
asynchronously. The code shouldn't know or care from which thread it is
called.

In some cases, I even find it unnecessary to have a "self" at all, a
thread can just as well run a non-member function. Also, even if it runs
a memberfunction initially, it doesn't have to eventually. I find that
forcing an OOP approach on things is flawed (OOP is a tool and not a
goal) and prefer to make this a decision, but that is a different
(although slightly related) issue.


Thirdly, when you derive a class from Thread, you are exposing this
baseclass' interface to the public, too, even if you don't intend to.
This has both the unwanted aspect that you expose all public functions
of the baseclass and that even if you mean "is a thread", it actually
means "is a handle to a thread", which is even less expressive.
Curously, you do that in order to override a single function that is
only invoked once. I prefer passing "instance.function" as callable
argument to a plain Thread instance for running this, which keeps the
two nicely separate.

For example, I have a TCP client class here that uses a service thread
to handle the data transfer. The fact that there is a background thread
should not be of concern to the user of my TCP client class. If I
extended this to use two threads, it would even be impossible to derive
from Thread for both of them.


In summary, I find that modelling something to "use a thread" is much
clearer than modelling it as "is a thread".

Greetings from Hamburg!

Uli
 
N

Ned Batchelder

Please post in plain text, not HTML.
Sorry, Bob, I will try to remember in the future. I think Thunderbird
is sending in the same format as the replied-to message, and I didn't
notice.

So that I understand what's going on, what's the bad thing that happens
with a multi-part message? I would have thought that mail readers would
choose the preferred part, or is it something to do with the message
quoting?

--Ned.

PS: Bob: email to you is bouncing, as excite.com says you don't exist.
 
D

Dennis Lee Bieber

So that I understand what's going on, what's the bad thing that happens
with a multi-part message? I would have thought that mail readers would
choose the preferred part, or is it something to do with the message
quoting?

Well... The main thing to understand is that this particular "forum" is
NOT JUST a mailing-list. It is cross-linked with the Usenet
comp.lang.python news-group (and that, unfortunately, is cross-linked to
Google-Groups). And to compound things, Gmane makes the mailing-list source
available as a news-group on their server.

So it isn't being viewed using just email clients -- I view it using a
newsreader.
 
S

Steven D'Aprano

So that I understand what's going on, what's the bad thing that happens
with a multi-part message? I would have thought that mail readers would
choose the preferred part, or is it something to do with the message
quoting?

This is not just a mailing list, it is also a newsgroup, and sending HTML
content to a text newsgroup is considered rude.

Just to add insult to injury, one of the most popular (and otherwise
excellent) news readers, Pan, treats HTML as "plain text", and displays
junk like this at the end of your HTML posts:

<html>
<head>
<meta content="text/html; charset=ISO-8859-1"
http-equiv="Content-Type">
</head>
<body bgcolor="#FFFFFF" text="#000000">
On 8/21/13 6:50 PM, F&aacute;bio Santos wrote:<br> <blockquote
cite="mid:CAA=1kxRdo0ZAH_SLvZshFua7B4A=9YZ1H30KBi-
(e-mail address removed)"
type="cite">
<p dir="ltr"><br>
On 21 Aug 2013 20:07, "Johannes Bauer" &lt;<a
...

but I don't blame the sender for that, I accept it as a misfeature in
Pan, which otherwise is one of the best news readers around.

But even if it were a mailing list, HTML mail is still harmful. Like lead
in petrol, it doesn't become less harmful because "everybody does it".
When your mail client renders HTML mail, you're effectively giving anyone
in the world permission to execute code in your mail reader, and trusting
that they won't abuse it. Or at least that your HTML display engine has
no vulnerabilities they can exploit. It allows them to embed web bugs in
their mail, and track when and if you read their mail, and that's not a
vulnerability, it's a feature.

If you've seen as many emails with orange text on a pink background with
yellow flowers and animated puppies as I have, you'll have a visceral
hatred of HTML email too.

And it inflates the size of the email, at best by a factor of 2 or 3, or
if they're using an editor like Microsoft Word that generates garbage for
HTML, by a factor or 20 or 30.
 
S

Steven D'Aprano

Firstly, there is one observation: The Python object of type Thread is
one thing, the actual thread is another thing. This is similar to the
File instance and the actual file. The Python object represents the
other thing (thread or file) but it "is not" this thing. It is rather a
handle to the file or thread. This is different for e.g. a string, where
the Python object is the string.

Well, not quite. To users coming from other languages, "string" has a
clear and common meaning; it's an array of characters, possibly fixed-
width in older languages, but these days usually variable-width but
prefixed with the length (as in Pascal) or suffixed with a delimiter
(usually \0, as in C). Or occasionally both.

So as far as those people are concerned, Python strings aren't just a
string. They are rich objects, with an object header. For example, we can
see that there is a whole bunch of extra "stuff" required of a Python
string before you even get to the array-of-characters:

py> sys.getsizeof('')
25

25 bytes to store an empty string. Even if it had a four-byte length, and
a four-byte NUL character at the end, that still leaves 17 bytes
unaccounted for. So obviously Python strings contain a whole lot more
than just low-level Pascal/C strings.

So while I agree that it is sometimes useful to distinguish between a
Python Thread object and the underlying low-level thread data structure
it wraps, we can do the same with strings (and floats, and lists, and
everything really). In any case, it's rare to need to do so.

Due to this pairing between the actual thing and the handle, there is
also some arity involved. For a single thread or file, there could be
multiple Python objects for handling it, or maybe even none.

I don't think this is correct for threads. I don't believe there is any
way to handle a low-level thread in Python except via an object of some
sort. (With files, you can use the os module to work with low-level OS
file descriptors, which are just integers.)

When the
Python object goes away, it doesn't necessarily affect the thread or
file it represents.

That's certainly not true with file objects. When the file object goes
out of scope, the underlying low-level file is closed.

This already casts a doubt on the habit of deriving
from the Thread type, just like deriving from the File type is highly
unusual, as you are just deriving from a handle class.

In Python 3, there is no "File" type. There are *multiple* file types,
depending on whether you open a file for reading or writing in binary or
text mode:

py> open('/tmp/junk', 'wb')
<_io.BufferedWriter name='/tmp/junk'>
py> open('/tmp/junk', 'rb')
<_io.BufferedReader name='/tmp/junk'>
py> open('/tmp/junk', 'w')
<_io.TextIOWrapper name='/tmp/junk' mode='w' encoding='UTF-8'>


But even if we limit the discussion to Python 2, it is unusual to inherit
from File because File already does everything we normally want from a
file. There's no need to override methods, so why make your own subclass?
On the other hand, threads by their very nature have to be customized.
The documentation is clear that there are two acceptable ways to do this:

This class represents an activity that is run in a separate
thread of control. 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.

http://docs.python.org/2/library/threading.html#thread-objects


So to some degree, it is just a matter of taste which you use.


[...]
In summary, I find that modelling something to "use a thread" is much
clearer than modelling it as "is a thread".

The rest of your arguments seem good to me, but not compelling. I think
they effectively boil down to personal taste. I write lots of non-OOP
code, but when it comes to threads, I prefer to subclass Thread.
 
R

random832

Well... The main thing to understand is that this particular "forum" is
NOT JUST a mailing-list. It is cross-linked with the Usenet
comp.lang.python news-group (and that, unfortunately, is cross-linked to
Google-Groups). And to compound things, Gmane makes the mailing-list
source
available as a news-group on their server.

So it isn't being viewed using just email clients -- I view it using a
newsreader.

I don't see how that's relevant, since newsreaders in general, and
(based on a quick google search for information about it) Forte Agent in
particular, have mime implementations as full-featured as any mail
client.
 
U

Ulrich Eckhardt

Am 23.08.2013 05:28, schrieb Steven D'Aprano:
That's certainly not true with file objects. When the file object goes
out of scope, the underlying low-level file is closed.

Ahem, yes, but no: Calling close(fd) is not the same as destroying the
file, I'm pretty sure it's still on my harddisk after that. That is also
the difference to strings, where the Python object really is all there
is to it. Similarly you can only customize the Python side of things
with derivation, the other side will remain the same, apart from the
data you write to the file or the code you run in the thread.

Steven, thank you for taking the time to read and consider what I wrote,
it is appreciated!

Uli
 
C

Chris Angelico

Am 23.08.2013 05:28, schrieb Steven D'Aprano:


Ahem, yes, but no: Calling close(fd) is not the same as destroying the file,
I'm pretty sure it's still on my harddisk after that. That is also the
difference to strings, where the Python object really is all there is to it.
Similarly you can only customize the Python side of things with derivation,
the other side will remain the same, apart from the data you write to the
file or the code you run in the thread.

The file object doesn't represent the file on the disk; it represents
the "open file", which is a thing that you can have a handle (file
descriptor) to. That "thing" is indeed destroyed when the file object
is __del__'d, though it's possible to dispose of it sooner than that:
f.write("Hello, world!")

13<_io.TextIOWrapper name='test' mode='w' encoding='cp1252'>

f has been closed at this point, and if I now go to open it in another
application, Python won't hold any locks; but the object still exists.
However, the general expectation is that the file object and the
open-file in the OS will correspond.

ChrisA
 

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

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,071
Latest member
MetabolicSolutionsKeto

Latest Threads

Top