Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #107640 > unrolled thread
| Started by | San <santanu01@gmail.com> |
|---|---|
| First post | 2016-04-25 23:21 -0700 |
| Last post | 2016-04-26 07:25 -0700 |
| Articles | 17 — 10 participants |
Back to article view | Back to comp.lang.python
def __init__(self): San <santanu01@gmail.com> - 2016-04-25 23:21 -0700
Re: def __init__(self): Ben Finney <ben+python@benfinney.id.au> - 2016-04-26 16:31 +1000
Re: def __init__(self): Gary Herron <gherron@digipen.edu> - 2016-04-26 00:06 -0700
Re: def __init__(self): Ben Finney <ben+python@benfinney.id.au> - 2016-04-26 17:34 +1000
Re: def __init__(self): Marko Rauhamaa <marko@pacujo.net> - 2016-04-26 11:25 +0300
Re: def __init__(self): Steven D'Aprano <steve@pearwood.info> - 2016-04-27 02:12 +1000
Re: def __init__(self): Random832 <random832@fastmail.com> - 2016-04-26 12:26 -0400
Re: def __init__(self): Steven D'Aprano <steve@pearwood.info> - 2016-04-27 02:32 +1000
Re: def __init__(self): Chris Kaynor <ckaynor@zindagigames.com> - 2016-04-26 09:59 -0700
Re: def __init__(self): Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2016-04-27 14:54 +1000
Re: def __init__(self): Chris Angelico <rosuav@gmail.com> - 2016-04-27 03:04 +1000
Re: def __init__(self): Chris Kaynor <ckaynor@zindagigames.com> - 2016-04-26 10:13 -0700
Re: def __init__(self): Ian Kelly <ian.g.kelly@gmail.com> - 2016-04-26 11:26 -0600
Re: def __init__(self): Chris Angelico <rosuav@gmail.com> - 2016-04-27 03:30 +1000
Re: def __init__(self): Marko Rauhamaa <marko@pacujo.net> - 2016-04-26 19:38 +0300
Re: def __init__(self): Random832 <random832@fastmail.com> - 2016-04-26 09:49 -0400
Re: def __init__(self): Gary Herron <gherron@digipen.edu> - 2016-04-26 07:25 -0700
| From | San <santanu01@gmail.com> |
|---|---|
| Date | 2016-04-25 23:21 -0700 |
| Subject | def __init__(self): |
| Message-ID | <34e51ef5-9679-40ec-bc8f-47981353e9d7@googlegroups.com> |
Hi All, Pls let me why " def __init__(self): " declaration required, what's the use of this one.Pls explain me in details. Thanks in advance.
[toc] | [next] | [standalone]
| From | Ben Finney <ben+python@benfinney.id.au> |
|---|---|
| Date | 2016-04-26 16:31 +1000 |
| Message-ID | <mailman.98.1461652308.32212.python-list@python.org> |
| In reply to | #107640 |
San <santanu01@gmail.com> writes: > Pls let me why […] declaration required, what's the use of this one. Welcome to Python! Congratulations on beginning to learn this language. > Pls explain me in details. You should participate in our collaborative tutoring forum, ‘tutor’ <URL:https://mail.python.org/mailman/listinfo/tutor> which is specially focussed on helping Python beginners. -- \ “Giving every man a vote has no more made men wise and free | `\ than Christianity has made them good.” —Henry L. Mencken | _o__) | Ben Finney
[toc] | [prev] | [next] | [standalone]
| From | Gary Herron <gherron@digipen.edu> |
|---|---|
| Date | 2016-04-26 00:06 -0700 |
| Message-ID | <mailman.99.1461654374.32212.python-list@python.org> |
| In reply to | #107640 |
On 04/25/2016 11:21 PM, San wrote:
> Hi All,
>
> Pls let me why
> "
> def __init__(self):
>
> "
> declaration required, what's the use of this one.Pls explain me in details.
>
> Thanks in advance.
If you understand object-oriented-programming, then this will make sense:
The __init__ method is the constructor for instances of a class. It
is not required, but the situations in which a constructor is not
needed are few and unusual.
If you don't know object-oriented-programming, then I'd suggest you put
that high on your list of things to learn. It's a valuable tool.
Gary Herron
--
Dr. Gary Herron
Professor of Computer Science
DigiPen Institute of Technology
(425) 895-4418
[toc] | [prev] | [next] | [standalone]
| From | Ben Finney <ben+python@benfinney.id.au> |
|---|---|
| Date | 2016-04-26 17:34 +1000 |
| Message-ID | <mailman.100.1461656092.32212.python-list@python.org> |
| In reply to | #107640 |
Gary Herron <gherron@digipen.edu> writes: > The __init__ method is the constructor for instances of a class. It > is not required, but the situations in which a constructor is not > needed are few and unusual. That's needlessly confusing: ‘__init__’ is not a constructor because it does not construct the instance. The ‘__new__’ method is the constructor for a class (and returns the new instance). The ‘__init__’ method requests the already-constructed instance to initialise itself (and returns None). -- \ “I still have my Christmas Tree. I looked at it today. Sure | `\ enough, I couldn't see any forests.” —Steven Wright | _o__) | Ben Finney
[toc] | [prev] | [next] | [standalone]
| From | Marko Rauhamaa <marko@pacujo.net> |
|---|---|
| Date | 2016-04-26 11:25 +0300 |
| Message-ID | <87lh40pyik.fsf@elektro.pacujo.net> |
| In reply to | #107644 |
Ben Finney <ben+python@benfinney.id.au>:
> Gary Herron <gherron@digipen.edu> writes:
>
>> The __init__ method is the constructor for instances of a class.
>> It is not required, but the situations in which a constructor is
>> not needed are few and unusual.
>
> That's needlessly confusing: ‘__init__’ is not a constructor because
> it does not construct the instance. The ‘__new__’ method is the
> constructor for a class (and returns the new instance).
I have never ever had a temptation to specify a __new__ method. I can't
imagine a *beneficial* case of overriding it.
> The ‘__init__’ method requests the already-constructed instance to
> initialise itself (and returns None).
It is a serious practical problem that an object can't guarantee that
its __init__ has been called.
Check out some of the stdlib source code for example:
========================================================================
class ThreadPoolExecutor(_base.Executor):
def __init__(self, max_workers):
"""Initializes a new ThreadPoolExecutor instance.
Args:
max_workers: The maximum number of threads that can be used to
execute the given calls.
"""
self._max_workers = max_workers
self._work_queue = queue.Queue()
self._threads = set()
self._shutdown = False
self._shutdown_lock = threading.Lock()
========================================================================
Notice how _base.Executor.__init__(self) does not get called. It can
only work if _base.Executor does not specify an __init__. That's an
assumption you really couldn't make with a clear conscience even if you
were the author and maintainer of both modules
(concurrent.futures.thread and concurrent.futures._base).
Marko
[toc] | [prev] | [next] | [standalone]
| From | Steven D'Aprano <steve@pearwood.info> |
|---|---|
| Date | 2016-04-27 02:12 +1000 |
| Message-ID | <571f9362$0$1602$c3e8da3$5496439d@news.astraweb.com> |
| In reply to | #107645 |
On Tue, 26 Apr 2016 06:25 pm, Marko Rauhamaa wrote: > Ben Finney <ben+python@benfinney.id.au>: > >> Gary Herron <gherron@digipen.edu> writes: >> >>> The __init__ method is the constructor for instances of a class. >>> It is not required, but the situations in which a constructor is >>> not needed are few and unusual. >> >> That's needlessly confusing: ‘__init__’ is not a constructor because >> it does not construct the instance. The ‘__new__’ method is the >> constructor for a class (and returns the new instance). > > I have never ever had a temptation to specify a __new__ method. I can't > imagine a *beneficial* case of overriding it. I'm afraid that's a failure of your imagination then. The obvious reason for overriding __new__ is to construct an immutable instance. You have to override __new__, because by the time it returns the instance is immutable and you can no longer initialise it. >> The ‘__init__’ method requests the already-constructed instance to >> initialise itself (and returns None). > > It is a serious practical problem that an object can't guarantee that > its __init__ has been called. No object can guarantee that any method is called. Python doesn't make an exception for __new__ or __init__. I'm not sure why you would want it to. > Check out some of the stdlib source code for example: > > ======================================================================== > class ThreadPoolExecutor(_base.Executor): > def __init__(self, max_workers): > """Initializes a new ThreadPoolExecutor instance. > > Args: > max_workers: The maximum number of threads that can be used to > execute the given calls. > """ > self._max_workers = max_workers > self._work_queue = queue.Queue() > self._threads = set() > self._shutdown = False > self._shutdown_lock = threading.Lock() > ======================================================================== > > Notice how _base.Executor.__init__(self) does not get called. What makes you think it needs to be called? > It can only work if _base.Executor does not specify an __init__. That's not the only way. For example, if the __init__ doesn't nothing, just like object.__init__. You can actually pass anything you like to object.__init__, and nothing happens: object.__init__([]) -- Steven
[toc] | [prev] | [next] | [standalone]
| From | Random832 <random832@fastmail.com> |
|---|---|
| Date | 2016-04-26 12:26 -0400 |
| Message-ID | <mailman.114.1461687970.32212.python-list@python.org> |
| In reply to | #107664 |
On Tue, Apr 26, 2016, at 12:12, Steven D'Aprano wrote: > The obvious reason for overriding __new__ is to construct an immutable > instance. You have to override __new__, because by the time it returns > the > instance is immutable and you can no longer initialise it. Other than by subclassing an existing immutable type written in C, is it actually possible to define a truly-immutable (rather than contract-immutable) class in python? (Of course, subclassing immutable C types is the more obvious answer to when you have to override __new__).
[toc] | [prev] | [next] | [standalone]
| From | Steven D'Aprano <steve@pearwood.info> |
|---|---|
| Date | 2016-04-27 02:32 +1000 |
| Message-ID | <571f9836$0$1619$c3e8da3$5496439d@news.astraweb.com> |
| In reply to | #107666 |
On Wed, 27 Apr 2016 02:26 am, Random832 wrote: > On Tue, Apr 26, 2016, at 12:12, Steven D'Aprano wrote: >> The obvious reason for overriding __new__ is to construct an immutable >> instance. You have to override __new__, because by the time it returns >> the >> instance is immutable and you can no longer initialise it. > > Other than by subclassing an existing immutable type written in C, is it > actually possible to define a truly-immutable (rather than > contract-immutable) class in python? No. Subclassing immutable built-ins is the most obvious and simple (and probably common) way to get an immutable class. Actually immutable, short of doing wicked things with ctypes. > (Of course, subclassing immutable C types is the more obvious answer to > when you have to override __new__). Indeed. -- Steven
[toc] | [prev] | [next] | [standalone]
| From | Chris Kaynor <ckaynor@zindagigames.com> |
|---|---|
| Date | 2016-04-26 09:59 -0700 |
| Message-ID | <mailman.116.1461690002.32212.python-list@python.org> |
| In reply to | #107669 |
On Tue, Apr 26, 2016 at 9:32 AM, Steven D'Aprano <steve@pearwood.info>
wrote:
> Subclassing immutable built-ins is the most obvious and simple (and
> probably
> common) way to get an immutable class. Actually immutable, short of doing
> wicked things with ctypes.
>
By wicked things with ctypes, do you mean something like this? By no means
do I suggest this actually be used by anybody for any reason.
Tested with '2.7.10 (default, Jul 14 2015, 19:46:27) \n[GCC 4.2.1
Compatible Apple LLVM 6.0 (clang-600.0.39)]'
import ctypes
def changeTuple(tuple, index, newValue):
obj = ctypes.cast(id(tuple), ctypes.POINTER(ctypes.c_long))
obj[3+index] = id(newValue)
>>> a = ('a','b','c')
>>> changeTuple(a, 0, 1)
>>> a
(1, 'b', 'c')
>>> changeTuple(a, 1, 3)
>>> a
(1, 3, 'c')
Chris
[toc] | [prev] | [next] | [standalone]
| From | Steven D'Aprano <steve+comp.lang.python@pearwood.info> |
|---|---|
| Date | 2016-04-27 14:54 +1000 |
| Message-ID | <57204605$0$11115$c3e8da3@news.astraweb.com> |
| In reply to | #107671 |
On Wednesday 27 April 2016 02:59, Chris Kaynor wrote:
> On Tue, Apr 26, 2016 at 9:32 AM, Steven D'Aprano <steve@pearwood.info>
> wrote:
>
>> Actually immutable, short of doing wicked things with ctypes.
>>
>
> By wicked things with ctypes, do you mean something like this? By no means
> do I suggest this actually be used by anybody for any reason.
>
> Tested with '2.7.10 (default, Jul 14 2015, 19:46:27) \n[GCC 4.2.1
> Compatible Apple LLVM 6.0 (clang-600.0.39)]'
>
> import ctypes
> def changeTuple(tuple, index, newValue):
> obj = ctypes.cast(id(tuple), ctypes.POINTER(ctypes.c_long))
> obj[3+index] = id(newValue)
>
>>>> a = ('a','b','c')
>>>> changeTuple(a, 0, 1)
>>>> a
> (1, 'b', 'c')
>>>> changeTuple(a, 1, 3)
>>>> a
> (1, 3, 'c')
You're a bad, bad man :-)
--
Steve
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2016-04-27 03:04 +1000 |
| Message-ID | <mailman.117.1461690250.32212.python-list@python.org> |
| In reply to | #107669 |
On Wed, Apr 27, 2016 at 2:59 AM, Chris Kaynor <ckaynor@zindagigames.com> wrote:
> On Tue, Apr 26, 2016 at 9:32 AM, Steven D'Aprano <steve@pearwood.info>
> wrote:
>
>> Subclassing immutable built-ins is the most obvious and simple (and
>> probably
>> common) way to get an immutable class. Actually immutable, short of doing
>> wicked things with ctypes.
>>
>
> By wicked things with ctypes, do you mean something like this? By no means
> do I suggest this actually be used by anybody for any reason.
>
> Tested with '2.7.10 (default, Jul 14 2015, 19:46:27) \n[GCC 4.2.1
> Compatible Apple LLVM 6.0 (clang-600.0.39)]'
>
> import ctypes
> def changeTuple(tuple, index, newValue):
> obj = ctypes.cast(id(tuple), ctypes.POINTER(ctypes.c_long))
> obj[3+index] = id(newValue)
>
>>>> a = ('a','b','c')
>>>> changeTuple(a, 0, 1)
>>>> a
> (1, 'b', 'c')
>>>> changeTuple(a, 1, 3)
>>>> a
> (1, 3, 'c')
Yeah. By the look of things, you've just destroyed the reference counts.
>>> a = ('a','b','c')
>>> b = object()
>>> changeTuple(a, 0, b)
>>> a
(<object object at 0x7f1240b22080>, 'b', 'c')
>>> del b
>>> a
Segmentation fault
ChrisA
[toc] | [prev] | [next] | [standalone]
| From | Chris Kaynor <ckaynor@zindagigames.com> |
|---|---|
| Date | 2016-04-26 10:13 -0700 |
| Message-ID | <mailman.118.1461690843.32212.python-list@python.org> |
| In reply to | #107669 |
On Tue, Apr 26, 2016 at 10:04 AM, Chris Angelico <rosuav@gmail.com> wrote:
> On Wed, Apr 27, 2016 at 2:59 AM, Chris Kaynor <ckaynor@zindagigames.com>
> wrote:
> > On Tue, Apr 26, 2016 at 9:32 AM, Steven D'Aprano <steve@pearwood.info>
> > wrote:
> >
> >> Subclassing immutable built-ins is the most obvious and simple (and
> >> probably
> >> common) way to get an immutable class. Actually immutable, short of
> doing
> >> wicked things with ctypes.
> >>
> >
> > By wicked things with ctypes, do you mean something like this? By no
> means
> > do I suggest this actually be used by anybody for any reason.
> >
> > Tested with '2.7.10 (default, Jul 14 2015, 19:46:27) \n[GCC 4.2.1
> > Compatible Apple LLVM 6.0 (clang-600.0.39)]'
> >
> > import ctypes
> > def changeTuple(tuple, index, newValue):
> > obj = ctypes.cast(id(tuple), ctypes.POINTER(ctypes.c_long))
> > obj[3+index] = id(newValue)
> >
> >>>> a = ('a','b','c')
> >>>> changeTuple(a, 0, 1)
> >>>> a
> > (1, 'b', 'c')
> >>>> changeTuple(a, 1, 3)
> >>>> a
> > (1, 3, 'c')
>
> Yeah. By the look of things, you've just destroyed the reference counts.
>
> >>> a = ('a','b','c')
> >>> b = object()
> >>> changeTuple(a, 0, b)
> >>> a
> (<object object at 0x7f1240b22080>, 'b', 'c')
> >>> del b
> >>> a
> Segmentation fault
>
Yah, if you really wanted to make it work properly, you'd need to incref
the newValue, while decref the oldValue. The incref would not be that
difficult, but the decref would be more challenging, as you may have to
also destroy the old object, though that might be possible by casting it
back to a python object without the incref,. One way or the other, I did
not exactly spend a ton of time to make it work properly :)
[toc] | [prev] | [next] | [standalone]
| From | Ian Kelly <ian.g.kelly@gmail.com> |
|---|---|
| Date | 2016-04-26 11:26 -0600 |
| Message-ID | <mailman.120.1461691656.32212.python-list@python.org> |
| In reply to | #107669 |
On Tue, Apr 26, 2016 at 11:13 AM, Chris Kaynor <ckaynor@zindagigames.com> wrote: > Yah, if you really wanted to make it work properly, you'd need to incref > the newValue, while decref the oldValue. The incref would not be that > difficult, but the decref would be more challenging, as you may have to > also destroy the old object, though that might be possible by casting it > back to a python object without the incref,. One way or the other, I did > not exactly spend a ton of time to make it work properly :) For the decref I'd probably just decrement it and leave it; if it's zero, the garbage collector will eventually take care of it.
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2016-04-27 03:30 +1000 |
| Message-ID | <mailman.121.1461691805.32212.python-list@python.org> |
| In reply to | #107669 |
On Wed, Apr 27, 2016 at 3:13 AM, Chris Kaynor <ckaynor@zindagigames.com> wrote:
> Yah, if you really wanted to make it work properly, you'd need to incref
> the newValue, while decref the oldValue. The incref would not be that
> difficult, but the decref would be more challenging, as you may have to
> also destroy the old object, though that might be possible by casting it
> back to a python object without the incref,. One way or the other, I did
> not exactly spend a ton of time to make it work properly :)
Exactly. :) Actually, the easiest fix is probably this:
import ctypes
def low_change_tuple(tuple, index, newValue):
obj = ctypes.cast(id(tuple), ctypes.POINTER(ctypes.c_long))
obj[3+index] = id(newValue)
def change_tuple(tup, idx, val):
dummy = (val,)
low_change_tuple(dummy, 0, tup[idx])
low_change_tuple(tup, idx, val)
Refcounts are handled by the switch.
ChrisA
[toc] | [prev] | [next] | [standalone]
| From | Marko Rauhamaa <marko@pacujo.net> |
|---|---|
| Date | 2016-04-26 19:38 +0300 |
| Message-ID | <87inz4uxyo.fsf@elektro.pacujo.net> |
| In reply to | #107664 |
Steven D'Aprano <steve@pearwood.info>: > On Tue, 26 Apr 2016 06:25 pm, Marko Rauhamaa wrote: >> Check out some of the stdlib source code for example: >> >> ======================================================================== >> class ThreadPoolExecutor(_base.Executor): >> def __init__(self, max_workers): >> """Initializes a new ThreadPoolExecutor instance. >> >> Args: >> max_workers: The maximum number of threads that can be used to >> execute the given calls. >> """ >> self._max_workers = max_workers >> self._work_queue = queue.Queue() >> self._threads = set() >> self._shutdown = False >> self._shutdown_lock = threading.Lock() >> ======================================================================== >> >> Notice how _base.Executor.__init__(self) does not get called. > > What makes you think it needs to be called? I would think that's somewhat of an axiom. Whenever I derive from a class, I consider it mandatory to delegate to its __init__ if my class specifies an __init__ itself. Otherwise, the underlying class must make a point to emphasize in its API documentation that __init__ is not needed. And the underlying class would be foolish to make such a contract because that would tie its hands in case the class needs refactoring in the future. Are you saying something else? See also <URL: https://docs.python.org/3/reference/datamodel.html?highlig ht=__init__#object.__init__>: If a base class has an __init__() method, the derived class’s __init__() method, if any, must explicitly call it to ensure proper initialization of the base class part of the instance I'm saying the derived class *must not* make any conclusions on the presence or absence of __init__ in the base class because that would be a gross violation of encapsulation. Marko
[toc] | [prev] | [next] | [standalone]
| From | Random832 <random832@fastmail.com> |
|---|---|
| Date | 2016-04-26 09:49 -0400 |
| Message-ID | <mailman.105.1461678569.32212.python-list@python.org> |
| In reply to | #107640 |
On Tue, Apr 26, 2016, at 03:34, Ben Finney wrote: > That's needlessly confusing: ‘__init__’ is not a constructor because it > does not construct the instance. The ‘__new__’ method is the constructor > for a class (and returns the new instance). the __new__ method is the *allocator*. "constructor" is used in many languages to name a method that initializes an object once it already "exists". Saying you can't call it that in Python is needlessly confusing.
[toc] | [prev] | [next] | [standalone]
| From | Gary Herron <gherron@digipen.edu> |
|---|---|
| Date | 2016-04-26 07:25 -0700 |
| Message-ID | <mailman.108.1461680734.32212.python-list@python.org> |
| In reply to | #107640 |
On 04/26/2016 06:49 AM, Random832 wrote: > On Tue, Apr 26, 2016, at 03:34, Ben Finney wrote: >> That's needlessly confusing: ‘__init__’ is not a constructor because it >> does not construct the instance. The ‘__new__’ method is the constructor >> for a class (and returns the new instance). > the __new__ method is the *allocator*. "constructor" is used in many > languages to name a method that initializes an object once it already > "exists". Saying you can't call it that in Python is needlessly > confusing. Agreed. For a newbie asking about __init__, I'll stick with my original answer (that it's the constructor), and suggest ignoring the overly pedantic (and confusing) response to the contrary. -- Dr. Gary Herron Professor of Computer Science DigiPen Institute of Technology (425) 895-4418
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.python
csiph-web