Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #52752 > unrolled thread

Basic Python Query

Started bychandan kumar <chandan_psr@yahoo.co.in>
First post2013-08-21 14:50 +0800
Last post2013-08-24 01:50 +1000
Articles 19 — 11 participants

Back to article view | Back to comp.lang.python


Contents

  Basic Python Query chandan kumar <chandan_psr@yahoo.co.in> - 2013-08-21 14:50 +0800
    Re: Basic Python Query Steven D'Aprano <steve@pearwood.info> - 2013-08-21 08:19 +0000
    Re: Basic Python Query Ulrich Eckhardt <ulrich.eckhardt@dominolaser.com> - 2013-08-21 11:11 +0200
      Re: Basic Python Query Johannes Bauer <dfnsonfsduifb@gmx.de> - 2013-08-21 20:58 +0200
        Re: Basic Python Query Fábio Santos <fabiosantosart@gmail.com> - 2013-08-21 23:50 +0100
          Re: Basic Python Query Johannes Bauer <dfnsonfsduifb@gmx.de> - 2013-08-22 10:49 +0200
        Re: Basic Python Query Ned Batchelder <ned@nedbatchelder.com> - 2013-08-21 20:06 -0400
          Re: Basic Python Query Bob Martin <bob.martin@excite.com> - 2013-08-22 06:43 +0100
            Re: Basic Python Query Ned Batchelder <ned@nedbatchelder.com> - 2013-08-22 09:45 -0400
              Re: Basic Python Query Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2013-08-23 03:12 +0000
            Re: Basic Python Query random832@fastmail.us - 2013-08-22 14:57 -0400
            Re: Basic Python Query Dennis Lee Bieber <wlfraed@ix.netcom.com> - 2013-08-22 18:22 -0400
            Re: Basic Python Query random832@fastmail.us - 2013-08-23 01:08 -0400
          Re: Basic Python Query Johannes Bauer <dfnsonfsduifb@gmx.de> - 2013-08-22 10:50 +0200
        Re: Basic Python Query Fábio Santos <fabiosantosart@gmail.com> - 2013-08-22 09:46 +0100
        Re: Basic Python Query Ulrich Eckhardt <ulrich.eckhardt@dominolaser.com> - 2013-08-22 13:54 +0200
          Re: Basic Python Query Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2013-08-23 03:28 +0000
            Re: Basic Python Query Ulrich Eckhardt <ulrich.eckhardt@dominolaser.com> - 2013-08-23 09:12 +0200
              Re: Basic Python Query Chris Angelico <rosuav@gmail.com> - 2013-08-24 01:50 +1000

#52752 — Basic Python Query

Fromchandan kumar <chandan_psr@yahoo.co.in>
Date2013-08-21 14:50 +0800
SubjectBasic Python Query
Message-ID<mailman.68.1377067974.19984.python-list@python.org>

[Multipart message — attachments visible in raw view] — view raw

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

[toc] | [next] | [standalone]


#52755

FromSteven D'Aprano <steve@pearwood.info>
Date2013-08-21 08:19 +0000
Message-ID<5214780f$0$29885$c3e8da3$5496439d@news.astraweb.com>
In reply to#52752
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. 



-- 
Steven

[toc] | [prev] | [next] | [standalone]


#52757

FromUlrich Eckhardt <ulrich.eckhardt@dominolaser.com>
Date2013-08-21 11:11 +0200
Message-ID<nqceea-aae.ln1@satorlaser.homedns.org>
In reply to#52752
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

[toc] | [prev] | [next] | [standalone]


#52784

FromJohannes Bauer <dfnsonfsduifb@gmx.de>
Date2013-08-21 20:58 +0200
Message-ID<kv32q9$rd2$1@news.albasani.net>
In reply to#52757
On 21.08.2013 11:11, Ulrich Eckhardt wrote:

> 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

-- 
>> Wo hattest Du das Beben nochmal GENAU vorhergesagt?
> 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 <hidbv3$om2$1@speranza.aioe.org>

[toc] | [prev] | [next] | [standalone]


#52800

FromFábio Santos <fabiosantosart@gmail.com>
Date2013-08-21 23:50 +0100
Message-ID<mailman.110.1377125778.19984.python-list@python.org>
In reply to#52784

[Multipart message — attachments visible in raw view] — view raw

On 21 Aug 2013 20:07, "Johannes Bauer" <dfnsonfsduifb@gmx.de> wrote:
>
> On 21.08.2013 11:11, Ulrich Eckhardt wrote:
>
> > 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

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.

[toc] | [prev] | [next] | [standalone]


#52823

FromJohannes Bauer <dfnsonfsduifb@gmx.de>
Date2013-08-22 10:49 +0200
Message-ID<kv4jbo$emp$1@news.albasani.net>
In reply to#52800
On 22.08.2013 00:50, Fábio Santos wrote:

>>> 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.
>>
> 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

-- 
>> Wo hattest Du das Beben nochmal GENAU vorhergesagt?
> 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 <hidbv3$om2$1@speranza.aioe.org>

[toc] | [prev] | [next] | [standalone]


#52802

FromNed Batchelder <ned@nedbatchelder.com>
Date2013-08-21 20:06 -0400
Message-ID<mailman.112.1377133512.19984.python-list@python.org>
In reply to#52784

[Multipart message — attachments visible in raw view] — view raw

On 8/21/13 6:50 PM, Fábio Santos wrote:
>
>
> On 21 Aug 2013 20:07, "Johannes Bauer" <dfnsonfsduifb@gmx.de 
> <mailto:dfnsonfsduifb@gmx.de>> wrote:
> >
> > On 21.08.2013 11:11, Ulrich Eckhardt wrote:
> >
> > > 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
>
> 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.

[toc] | [prev] | [next] | [standalone]


#52811

FromBob Martin <bob.martin@excite.com>
Date2013-08-22 06:43 +0100
Message-ID<b7lmo1Fpk52U1@mid.individual.net>
In reply to#52802
in 704175 20130822 010625 Ned Batchelder <ned@nedbatchelder.com> wrote:
>This is a multi-part message in MIME format.

Please post in plain text, not HTML.

[toc] | [prev] | [next] | [standalone]


#52841

FromNed Batchelder <ned@nedbatchelder.com>
Date2013-08-22 09:45 -0400
Message-ID<mailman.138.1377194018.19984.python-list@python.org>
In reply to#52811
On 8/22/13 1:43 AM, Bob Martin wrote:
> in 704175 20130822 010625 Ned Batchelder <ned@nedbatchelder.com> wrote:
>> This is a multi-part message in MIME format.
> 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.

[toc] | [prev] | [next] | [standalone]


#52860

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2013-08-23 03:12 +0000
Message-ID<5216d333$0$29986$c3e8da3$5496439d@news.astraweb.com>
In reply to#52841
On Thu, 22 Aug 2013 09:45:43 -0400, Ned Batchelder wrote:

> 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-
    KAGqDXiovVg@mail.gmail.com"
      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.



-- 
Steven

[toc] | [prev] | [next] | [standalone]


#52842

Fromrandom832@fastmail.us
Date2013-08-22 14:57 -0400
Message-ID<mailman.139.1377197878.19984.python-list@python.org>
In reply to#52811
On Thu, Aug 22, 2013, at 9:45, Ned Batchelder wrote:
> 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?

The bad thing that happens is baby Jesus cries.

In other words, some people just don't like it, for no better reason
than personal ideology (and/or they have a non-mime email client and
don't like seeing the extra encoded stuff, and/or they have a fully HTML
capable email client, don't like it, and can't be bothered learning how
to turn off HTML viewing). There's really no way to have a productive
discussion about it (though it might be worthwhile to ask whoever is in
charge of the list to make it automatically strip html from messages, if
enough people have a strong preference)

[toc] | [prev] | [next] | [standalone]


#52849

FromDennis Lee Bieber <wlfraed@ix.netcom.com>
Date2013-08-22 18:22 -0400
Message-ID<mailman.144.1377210167.19984.python-list@python.org>
In reply to#52811
On Thu, 22 Aug 2013 09:45:43 -0400, Ned Batchelder <ned@nedbatchelder.com>
declaimed the following:

>
>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.
	
-- 
	Wulfraed                 Dennis Lee Bieber         AF6VN
    wlfraed@ix.netcom.com    HTTP://wlfraed.home.netcom.com/

[toc] | [prev] | [next] | [standalone]


#52864

Fromrandom832@fastmail.us
Date2013-08-23 01:08 -0400
Message-ID<mailman.151.1377234518.19984.python-list@python.org>
In reply to#52811
On Thu, Aug 22, 2013, at 18:22, Dennis Lee Bieber wrote:
> 	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.

[toc] | [prev] | [next] | [standalone]


#52824

FromJohannes Bauer <dfnsonfsduifb@gmx.de>
Date2013-08-22 10:50 +0200
Message-ID<kv4jd1$emp$2@news.albasani.net>
In reply to#52802
On 22.08.2013 02:06, Ned Batchelder wrote:

>> 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."

Yup, that's what I was aiming for.

Best regards,
Johannes

-- 
>> Wo hattest Du das Beben nochmal GENAU vorhergesagt?
> 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 <hidbv3$om2$1@speranza.aioe.org>

[toc] | [prev] | [next] | [standalone]


#52822

FromFábio Santos <fabiosantosart@gmail.com>
Date2013-08-22 09:46 +0100
Message-ID<mailman.125.1377161201.19984.python-list@python.org>
In reply to#52784

[Multipart message — attachments visible in raw view] — view raw

On 22 Aug 2013 08:58, "chandan kumar" <chandan_psr@yahoo.co.in> wrote:
>
> 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__.

[toc] | [prev] | [next] | [standalone]


#52828

FromUlrich Eckhardt <ulrich.eckhardt@dominolaser.com>
Date2013-08-22 13:54 +0200
Message-ID<6oahea-u2n.ln1@satorlaser.homedns.org>
In reply to#52784
Am 21.08.2013 20:58, schrieb Johannes Bauer:
> On 21.08.2013 11:11, Ulrich Eckhardt wrote:
>
>> 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.

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

[toc] | [prev] | [next] | [standalone]


#52861

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2013-08-23 03:28 +0000
Message-ID<5216d6cc$0$29986$c3e8da3$5496439d@news.astraweb.com>
In reply to#52828
On Thu, 22 Aug 2013 13:54:14 +0200, Ulrich Eckhardt wrote:

> 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.


-- 
Steven

[toc] | [prev] | [next] | [standalone]


#52868

FromUlrich Eckhardt <ulrich.eckhardt@dominolaser.com>
Date2013-08-23 09:12 +0200
Message-ID<kkejea-2bs.ln1@satorlaser.homedns.org>
In reply to#52861
Am 23.08.2013 05:28, schrieb Steven D'Aprano:
> On Thu, 22 Aug 2013 13:54:14 +0200, Ulrich Eckhardt wrote:
>> When the Python object goes away, it doesn't necessarily affect
>> thethread 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.

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

[toc] | [prev] | [next] | [standalone]


#52897

FromChris Angelico <rosuav@gmail.com>
Date2013-08-24 01:50 +1000
Message-ID<mailman.167.1377273054.19984.python-list@python.org>
In reply to#52868
On Fri, Aug 23, 2013 at 5:12 PM, Ulrich Eckhardt
<ulrich.eckhardt@dominolaser.com> wrote:
> Am 23.08.2013 05:28, schrieb Steven D'Aprano:
>>
>> On Thu, 22 Aug 2013 13:54:14 +0200, Ulrich Eckhardt wrote:
>>>
>>> When the Python object goes away, it doesn't necessarily affect
>>> thethread 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.
>
>
> 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 = open("test","w")
>>> with f:
	f.write("Hello, world!")

13
>>> f
<_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

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.python


csiph-web