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


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

SIngleton from __defaults__

Started byAsaf Las <roegltd@gmail.com>
First post2014-01-22 08:07 -0800
Last post2014-01-22 14:34 -0800
Articles 12 — 7 participants

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


Contents

  SIngleton from __defaults__ Asaf Las <roegltd@gmail.com> - 2014-01-22 08:07 -0800
    Re: SIngleton from __defaults__ Chris Angelico <rosuav@gmail.com> - 2014-01-23 03:18 +1100
      Re: SIngleton from __defaults__ Asaf Las <roegltd@gmail.com> - 2014-01-22 08:37 -0800
        Re: SIngleton from __defaults__ 88888 Dihedral <dihedral88888@gmail.com> - 2014-01-22 09:23 -0800
        Re: SIngleton from __defaults__ Ned Batchelder <ned@nedbatchelder.com> - 2014-01-22 14:18 -0500
          Re: SIngleton from __defaults__ Asaf Las <roegltd@gmail.com> - 2014-01-22 11:52 -0800
        Re: SIngleton from __defaults__ Johannes Schneider <johannes.schneider@galileo-press.de> - 2014-01-23 14:36 +0100
        Re: SIngleton from __defaults__ Dave Angel <davea@davea.name> - 2014-01-23 11:56 -0500
        Re: SIngleton from __defaults__ Terry Reedy <tjreedy@udel.edu> - 2014-01-23 19:10 -0500
        Re: SIngleton from __defaults__ Johannes Schneider <johannes.schneider@galileo-press.de> - 2014-01-24 09:20 +0100
      Re: SIngleton from __defaults__ Asaf Las <roegltd@gmail.com> - 2014-01-22 13:10 -0800
      Re: SIngleton from __defaults__ Asaf Las <roegltd@gmail.com> - 2014-01-22 14:34 -0800

#64507 — SIngleton from __defaults__

FromAsaf Las <roegltd@gmail.com>
Date2014-01-22 08:07 -0800
SubjectSIngleton from __defaults__
Message-ID<26ff768d-349c-48cd-a46f-25343807e18a@googlegroups.com>
Hi 

Inspired by "Modifying the default argument of function"
https://groups.google.com/forum/#!topic/comp.lang.python/1xtFE6uScaI

is it possible to create singleton using construct below : 

def singleton_provider(x = [None]):
    if singleton_provider.__defaults__[0][0] == None:
        singleton_provider.__defaults__[0][0] = SomeClass()
    return singleton_provider.__defaults__[0][0]

and question - how to make it work in multithreaded app
when multiple threads are racing to create it first?

Thanks 

Asaf

[toc] | [next] | [standalone]


#64508

FromChris Angelico <rosuav@gmail.com>
Date2014-01-23 03:18 +1100
Message-ID<mailman.5843.1390407541.18130.python-list@python.org>
In reply to#64507
On Thu, Jan 23, 2014 at 3:07 AM, Asaf Las <roegltd@gmail.com> wrote:
> is it possible to create singleton using construct below :
>
> def singleton_provider(x = [None]):
>     if singleton_provider.__defaults__[0][0] == None:
>         singleton_provider.__defaults__[0][0] = SomeClass()
>     return singleton_provider.__defaults__[0][0]
>

Why not simply:

def get_singleton(x = SomeClass()):
    return x

Or even:

singleton = SomeClass()

? Neither of the above provides anything above the last one, except
for late creation.

ChrisA

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


#64510

FromAsaf Las <roegltd@gmail.com>
Date2014-01-22 08:37 -0800
Message-ID<d4053869-c668-4b5d-8e58-25b3650307df@googlegroups.com>
In reply to#64508
On Wednesday, January 22, 2014 6:18:57 PM UTC+2, Chris Angelico wrote:
> On Thu, Jan 23, 2014 at 3:07 AM, Asaf Las <r....@gmail.com> wrote:
> 
> Why not simply:
> def get_singleton(x = SomeClass()):
>     return x
> Or even:
> singleton = SomeClass()
> ? Neither of the above provides anything above the last one, except
> for late creation.
> 
> ChrisA

Actually need was to have some interface to running independent threads
to give same and once created object always.

For first  - SomeClass's object will be created whenever there will be 
call to get_singleton().
For second, again it is free to create it whenever someone (thread) 
wish. 

Hmmm, use case was to create persistent counter in multithreaded app
accessing single file where incrementing integer is stored.
When my imagination expanded it onto multiprocessing mess i ended up 
using sqlite access to DB in exclusive transaction mode. 
But this was not pythonic :-) 

Asaf

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


#64516

From88888 Dihedral <dihedral88888@gmail.com>
Date2014-01-22 09:23 -0800
Message-ID<d5d7bae2-2df1-4367-b45b-c5aa06062d47@googlegroups.com>
In reply to#64510
On Thursday, January 23, 2014 12:37:36 AM UTC+8, Asaf Las wrote:
> On Wednesday, January 22, 2014 6:18:57 PM UTC+2, Chris Angelico wrote:
> 
> > On Thu, Jan 23, 2014 at 3:07 AM, Asaf Las <r....@gmail.com> wrote:
> 
> > 
> 
> > Why not simply:
> 
> > def get_singleton(x = SomeClass()):
> 
> >     return x
> 
> > Or even:
> 
> > singleton = SomeClass()
> 
> > ? Neither of the above provides anything above the last one, except
> 
> > for late creation.
> 
> > 
> 
> > ChrisA
> 
> 
> 
> Actually need was to have some interface to running independent threads
> 
> to give same and once created object always.
> 
> 
> 
> For first  - SomeClass's object will be created whenever there will be 
> 
> call to get_singleton().
> 
> For second, again it is free to create it whenever someone (thread) 
> 
> wish. 
> 
> 
> 
> Hmmm, use case was to create persistent counter in multithreaded app
> 
> accessing single file where incrementing integer is stored.
> 
> When my imagination expanded it onto multiprocessing mess i ended up 
> 
> using sqlite access to DB in exclusive transaction mode. 
> 
> But this was not pythonic :-) 
> 
> 
> 
> Asaf

In a high level  language such as Python, functions and class initilizers
are the first class objects.

Don't you get the proof?
Everyting OOP is equivalent to everything functional but  it is much trivial to debug  by the designer  
than the old grandma lisp.

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


#64527

FromNed Batchelder <ned@nedbatchelder.com>
Date2014-01-22 14:18 -0500
Message-ID<mailman.5848.1390418313.18130.python-list@python.org>
In reply to#64510
On 1/22/14 11:37 AM, Asaf Las wrote:
> On Wednesday, January 22, 2014 6:18:57 PM UTC+2, Chris Angelico wrote:
>> On Thu, Jan 23, 2014 at 3:07 AM, Asaf Las <r....@gmail.com> wrote:
>>
>> Why not simply:
>> def get_singleton(x = SomeClass()):
>>      return x
>> Or even:
>> singleton = SomeClass()
>> ? Neither of the above provides anything above the last one, except
>> for late creation.
>>
>> ChrisA
>
> Actually need was to have some interface to running independent threads
> to give same and once created object always.
>
> For first  - SomeClass's object will be created whenever there will be
> call to get_singleton().

No, the value for a function argument's default is computed once when 
the function is defined.  Chris is right: get_singleton will always 
return the same object.

> For second, again it is free to create it whenever someone (thread)
> wish.

Chris is right here, too: modules are themselves singletons, no matter 
how many times you import them, they are only executed once, and the 
same module object is provided for each import.

>
> Hmmm, use case was to create persistent counter in multithreaded app
> accessing single file where incrementing integer is stored.
> When my imagination expanded it onto multiprocessing mess i ended up
> using sqlite access to DB in exclusive transaction mode.
> But this was not pythonic :-)
>
> Asaf
>


-- 
Ned Batchelder, http://nedbatchelder.com

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


#64531

FromAsaf Las <roegltd@gmail.com>
Date2014-01-22 11:52 -0800
Message-ID<a119d2c3-30ab-4361-a39d-3ed2a52ad26b@googlegroups.com>
In reply to#64527
On Wednesday, January 22, 2014 9:18:19 PM UTC+2, Ned Batchelder wrote:
> Chris is right here, too: modules are themselves singletons, no matter 
> how many times you import them, they are only executed once, and the 
> same module object is provided for each import.
> 
> Ned Batchelder, http://nedbatchelder.com

Chris, Ned, many thanks for clarification! 

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


#64605

FromJohannes Schneider <johannes.schneider@galileo-press.de>
Date2014-01-23 14:36 +0100
Message-ID<mailman.5888.1390484172.18130.python-list@python.org>
In reply to#64510
On 22.01.2014 20:18, Ned Batchelder wrote:
> On 1/22/14 11:37 AM, Asaf Las wrote:
> Chris is right here, too: modules are themselves singletons, no matter
> how many times you import them, they are only executed once, and the
> same module object is provided for each import.

I'm not sure, if this is the whole truth.

think about this example:

cat bla.py
a = 10

cat foo.py
from bla import a

def stuff():
         return a

cat bar.py
from foo import stuff
print stuff()
a = 5
print stuff()

from bla import *
print a

python bar.py
10
10
10

here the a is coming from bla and is known in the global namespace. But 
the value differs in stuff() and before/after the import statement. So 
the instance of the module differs -> it cannot be a singelton.

bg,
Johannes

-- 
Johannes Schneider
Webentwicklung
johannes.schneider@galileo-press.de
Tel.: +49.228.42150.xxx

Galileo Press GmbH
Rheinwerkallee 4 - 53227 Bonn - Germany
Tel.: +49.228.42.150.0 (Zentrale) .77 (Fax)
http://www.galileo-press.de/

Geschäftsführer: Tomas Wehren, Ralf Kaulisch, Rainer Kaltenecker
HRB 8363 Amtsgericht Bonn

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


#64622

FromDave Angel <davea@davea.name>
Date2014-01-23 11:56 -0500
Message-ID<mailman.5899.1390496064.18130.python-list@python.org>
In reply to#64510
 Johannes Schneider <johannes.schneider@galileo-press.de> Wrote in
 message:
> On 22.01.2014 20:18, Ned Batchelder wrote:
>> On 1/22/14 11:37 AM, Asaf Las wrote:
>> Chris is right here, too: modules are themselves singletons, no matter
>> how many times you import them, they are only executed once, and the
>> same module object is provided for each import.
> 
> I'm not sure, if this is the whole truth.
> 
> think about this example:
> 
> cat bla.py
> a = 10
> 
> cat foo.py
> from bla import a
> 
> def stuff():
>          return a
> 
> cat bar.py
> from foo import stuff
> print stuff()
> a = 5
> print stuff()
> 
> from bla import *
> print a
> 
> python bar.py
> 10
> 10
> 10
> 
> here the a is coming from bla and is known in the global namespace. But 
> the value differs in stuff() and before/after the import statement. So 
> the instance of the module differs -> it cannot be a singelton.
> 

You're using 3 different variables here, each global to its own
 module. If you really want to access the same object, you need to
 reference it as bla.a. And ditch the from deal.

A  from x import y. statement produces a new binding to the same
 object.  But since the object in your example is immutable,  the
 only way it can seem to change is by rebinding.  If several names
 are bound to the same object,  rebinding one has no effect on the
 others. 

-- 
DaveA

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


#64644

FromTerry Reedy <tjreedy@udel.edu>
Date2014-01-23 19:10 -0500
Message-ID<mailman.5916.1390522230.18130.python-list@python.org>
In reply to#64510
>   Johannes Schneider <johannes.schneider@galileo-press.de> Wrote in
>   message:
>> On 22.01.2014 20:18, Ned Batchelder wrote:
>>> On 1/22/14 11:37 AM, Asaf Las wrote:
>>> Chris is right here, too: modules are themselves singletons, no matter
>>> how many times you import them, they are only executed once, and the
>>> same module object is provided for each import.
>>
>> I'm not sure, if this is the whole truth.
>>
>> think about this example:
>>
>> cat bla.py
>> a = 10
>>
>> cat foo.py
>> from bla import a

This makes a a global in foo, bound to 10

>> def stuff():
>>           return a

This a refers to the global a in foo.

>> cat bar.py
>> from foo import stuff
>> print stuff()
>> a = 5

This bar.a is irrelevant to the behavior of stuff.

>> print stuff()
>>
>> from bla import *
>> print a
>>
>> python bar.py
>> 10

foo.a == 10

>> 10

foo.a == 10

>> 10

bla.a == 10

>> here the a is coming from bla

Twice

and is known in the global namespace.

There is no global namespace outside of modules.

>> the value differs in stuff()

No it does not.

and before/after the import statement.

foo.a does not change. bar.a is never used.

>> So the instance of the module differs

Nope. Each of the three module instances is constant. The bindings 
within each could change, but there are no rebinding in the code above.

-- 
Terry Jan Reedy

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


#64666

FromJohannes Schneider <johannes.schneider@galileo-press.de>
Date2014-01-24 09:20 +0100
Message-ID<mailman.5931.1390551625.18130.python-list@python.org>
In reply to#64510
thnx guys.

On 24.01.2014 01:10, Terry Reedy wrote:
>>   Johannes Schneider <johannes.schneider@galileo-press.de> Wrote in
>>   message:
>>> On 22.01.2014 20:18, Ned Batchelder wrote:
>>>> On 1/22/14 11:37 AM, Asaf Las wrote:
>>>> Chris is right here, too: modules are themselves singletons, no matter
>>>> how many times you import them, they are only executed once, and the
>>>> same module object is provided for each import.
>>>
>>> I'm not sure, if this is the whole truth.
>>>
>>> think about this example:
>>>
>>> cat bla.py
>>> a = 10
>>>
>>> cat foo.py
>>> from bla import a
>
> This makes a a global in foo, bound to 10
>
>>> def stuff():
>>>           return a
>
> This a refers to the global a in foo.
>
>>> cat bar.py
>>> from foo import stuff
>>> print stuff()
>>> a = 5
>
> This bar.a is irrelevant to the behavior of stuff.
>
>>> print stuff()
>>>
>>> from bla import *
>>> print a
>>>
>>> python bar.py
>>> 10
>
> foo.a == 10
>
>>> 10
>
> foo.a == 10
>
>>> 10
>
> bla.a == 10
>
>>> here the a is coming from bla
>
> Twice
>
> and is known in the global namespace.
>
> There is no global namespace outside of modules.
>
>>> the value differs in stuff()
>
> No it does not.
>
> and before/after the import statement.
>
> foo.a does not change. bar.a is never used.
>
>>> So the instance of the module differs
>
> Nope. Each of the three module instances is constant. The bindings
> within each could change, but there are no rebinding in the code above.
>


-- 
Johannes Schneider
Webentwicklung
johannes.schneider@galileo-press.de
Tel.: +49.228.42150.xxx

Galileo Press GmbH
Rheinwerkallee 4 - 53227 Bonn - Germany
Tel.: +49.228.42.150.0 (Zentrale) .77 (Fax)
http://www.galileo-press.de/

Geschäftsführer: Tomas Wehren, Ralf Kaulisch, Rainer Kaltenecker
HRB 8363 Amtsgericht Bonn

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


#64535

FromAsaf Las <roegltd@gmail.com>
Date2014-01-22 13:10 -0800
Message-ID<48967ec6-e766-436f-848f-103b871cacec@googlegroups.com>
In reply to#64508
On Wednesday, January 22, 2014 6:18:57 PM UTC+2, Chris Angelico wrote:
> On Thu, Jan 23, 2014 at 3:07 AM, Asaf Las <r...@gmail.com> wrote:
> > is it possible to create singleton using construct below :
> >
> > def singleton_provider(x = [None]):
> >     if singleton_provider.__defaults__[0][0] == None:
> >         singleton_provider.__defaults__[0][0] = SomeClass()
> >     return singleton_provider.__defaults__[0][0]
> >
> 
> Why not simply:
> def get_singleton(x = SomeClass()):
>     return x
> Or even:
> singleton = SomeClass()
> ? Neither of the above provides anything above the last one, except
> for late creation.
> ChrisA

Hi Chris

Does it make sense to use former as template to make 
singleton from any class as below, so instead of addressing 
your second proposal using module name we can directly call 
this one supplying class candidate for singleness as argument
to function? 

class whatever():
    def __init__(self):
        self.one = 1
        self.zero = 0

def singleton_provider(someclass, x = [None]):
    if singleton_provider.__defaults__[0][0] == None:
        singleton_provider.__defaults__[0][0] = someclass()
    return singleton_provider.__defaults__[0][0]


print(id(singleton_provider(whatever)))

Thanks 

Asaf

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


#64540

FromAsaf Las <roegltd@gmail.com>
Date2014-01-22 14:34 -0800
Message-ID<59440b67-9c35-441d-87a8-a2cadc1af02f@googlegroups.com>
In reply to#64508
On Wednesday, January 22, 2014 6:18:57 PM UTC+2, Chris Angelico wrote:
> On Thu, Jan 23, 2014 at 3:07 AM, Asaf Las <r...@gmail.com> wrote:
> ChrisA

and this one is about multiclass container function with 
multithreading support:

import threading

def provider(cls, x = [threading.Lock(), {}]):
    provider.__defaults__[0][0].acquire()
    if not cls.__name__ in provider.__defaults__[0][1]:
        provider.__defaults__[0][1][cls.__name__] = cls()
    provider.__defaults__[0][0].release()
    return provider.__defaults__[0][1][cls.__name__]


class whatever():
    def __init__(self):
        self.one = 1
        self.zero = 0

class whatever1():
    def __init__(self):
        self.one = 1
        self.zero = 0

    
print(id(provider(whatever)))
print(id(provider(whatever)))
print(id(provider(whatever1)))
print(id(provider(whatever1)))

could be there some hidden faults i missed? 

/Asaf

[toc] | [prev] | [standalone]


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


csiph-web