Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #65995 > unrolled thread
| Started by | Asaf Las <roegltd@gmail.com> |
|---|---|
| First post | 2014-02-11 20:34 -0800 |
| Last post | 2014-02-12 15:05 -0700 |
| Articles | 20 on this page of 40 — 15 participants |
Back to article view | Back to comp.lang.python
singleton ... again Asaf Las <roegltd@gmail.com> - 2014-02-11 20:34 -0800
Re: singleton ... again Asaf Las <roegltd@gmail.com> - 2014-02-11 21:15 -0800
Re:singleton ... again Dave Angel <davea@davea.name> - 2014-02-12 00:48 -0500
Re: singleton ... again Roy Smith <roy@panix.com> - 2014-02-12 00:55 -0500
Re: singleton ... again Gregory Ewing <greg.ewing@canterbury.ac.nz> - 2014-02-12 23:04 +1300
Re: singleton ... again Ben Finney <ben+python@benfinney.id.au> - 2014-02-12 21:09 +1100
Re: singleton ... again Roy Smith <roy@panix.com> - 2014-02-12 08:40 -0500
Re: singleton ... again Piet van Oostrum <piet@vanoostrum.org> - 2014-02-13 10:00 +0100
Re: singleton ... again Ned Batchelder <ned@nedbatchelder.com> - 2014-02-13 06:50 -0500
Re: singleton ... again Chris Angelico <rosuav@gmail.com> - 2014-02-13 22:57 +1100
Re: singleton ... again Roy Smith <roy@panix.com> - 2014-02-13 10:24 -0500
Re: singleton ... again Chris Angelico <rosuav@gmail.com> - 2014-02-14 07:03 +1100
Re: singleton ... again Robert Kern <robert.kern@gmail.com> - 2014-02-13 21:13 +0000
Re: singleton ... again Chris Angelico <rosuav@gmail.com> - 2014-02-14 08:27 +1100
Re: singleton ... again Ethan Furman <ethan@stoneleaf.us> - 2014-02-13 08:57 -0800
Re: singleton ... again Roy Smith <roy@panix.com> - 2014-02-13 12:57 -0500
Re: singleton ... again Ethan Furman <ethan@stoneleaf.us> - 2014-02-13 10:31 -0800
Re: singleton ... again Roy Smith <roy@panix.com> - 2014-02-13 14:03 -0500
Re: singleton ... again Chris Angelico <rosuav@gmail.com> - 2014-02-14 06:50 +1100
Re: singleton ... again Grant Edwards <invalid@invalid.invalid> - 2014-02-13 22:28 +0000
Re: singleton ... again Gregory Ewing <greg.ewing@canterbury.ac.nz> - 2014-02-14 18:21 +1300
Re: singleton ... again Tim Delaney <timothy.c.delaney@gmail.com> - 2014-02-14 06:16 +1100
Re: singleton ... again Steven D'Aprano <steve@pearwood.info> - 2014-02-13 02:58 +0000
Re: singleton ... again Ben Finney <ben+python@benfinney.id.au> - 2014-02-13 14:07 +1100
Re: singleton ... again Steven D'Aprano <steve@pearwood.info> - 2014-02-13 04:24 +0000
Re: singleton ... again Chris Angelico <rosuav@gmail.com> - 2014-02-13 15:33 +1100
Re: singleton ... again Gregory Ewing <greg.ewing@canterbury.ac.nz> - 2014-02-14 18:15 +1300
Re: singleton ... again Gregory Ewing <greg.ewing@canterbury.ac.nz> - 2014-02-14 18:06 +1300
Re: singleton ... again Asaf Las <roegltd@gmail.com> - 2014-02-12 09:50 -0800
Re: singleton ... again Asaf Las <roegltd@gmail.com> - 2014-02-12 09:56 -0800
Re: singleton ... again Asaf Las <roegltd@gmail.com> - 2014-02-12 09:58 -0800
Re: singleton ... again Gregory Ewing <greg.ewing@canterbury.ac.nz> - 2014-02-13 10:57 +1300
Re: singleton ... again Asaf Las <roegltd@gmail.com> - 2014-02-12 17:38 -0800
Re: singleton ... again Mark Lawrence <breamoreboy@yahoo.co.uk> - 2014-02-12 18:57 +0000
Re: singleton ... again Asaf Las <roegltd@gmail.com> - 2014-02-12 17:02 -0800
Re: singleton ... again Ned Batchelder <ned@nedbatchelder.com> - 2014-02-12 16:34 -0500
Re: singleton ... again Asaf Las <roegltd@gmail.com> - 2014-02-12 17:34 -0800
Re: singleton ... again Tim Delaney <timothy.c.delaney@gmail.com> - 2014-02-13 10:08 +1100
Re: singleton ... again Roy Smith <roy@panix.com> - 2014-02-12 20:57 -0500
Re: singleton ... again Michael Torrie <torriem@gmail.com> - 2014-02-12 15:05 -0700
Page 1 of 2 [1] 2 Next page →
| From | Asaf Las <roegltd@gmail.com> |
|---|---|
| Date | 2014-02-11 20:34 -0800 |
| Subject | singleton ... again |
| Message-ID | <fdbb58a7-87c0-4a2f-bedf-f8e3e14fa356@googlegroups.com> |
playing a bit with subject.
pros and cons of this approach? did i create bicycle again? :-)
class myclass(object):
class_instance = None
def __new__(cls, *args, **kwargs):
if myclass.class_instance == None:
return object.__new__(cls)
return myclass.class_instance
def __init__(self, some):
if self.__class__.class_instance == None: # init blocker
self.__class__.class_instance = self
self.member = some
def __del__(self):
self.__class__.class_instance = None
one_class = myclass(1)
print(id(one_class), one_class.member )
two_class = myclass(2)
print(id(two_class), two_class.member)
[toc] | [next] | [standalone]
| From | Asaf Las <roegltd@gmail.com> |
|---|---|
| Date | 2014-02-11 21:15 -0800 |
| Message-ID | <d1748b1f-bbe0-482d-97dd-492318d68283@googlegroups.com> |
| In reply to | #65995 |
there is error should assign weakref to class static member otherwise __del__ will never be called.
[toc] | [prev] | [next] | [standalone]
| From | Dave Angel <davea@davea.name> |
|---|---|
| Date | 2014-02-12 00:48 -0500 |
| Message-ID | <mailman.6728.1392183929.18130.python-list@python.org> |
| In reply to | #65995 |
Asaf Las <roegltd@gmail.com> Wrote in message: > playing a bit with subject. > > pros and cons of this approach? did i create bicycle again? :-) > > class myclass(object): > class_instance = None > > def __new__(cls, *args, **kwargs): > if myclass.class_instance == None: > return object.__new__(cls) > return myclass.class_instance > > def __init__(self, some): > if self.__class__.class_instance == None: # init blocker > self.__class__.class_instance = self > self.member = some > > def __del__(self): > self.__class__.class_instance = None > > one_class = myclass(1) > print(id(one_class), one_class.member ) > > two_class = myclass(2) > print(id(two_class), two_class.member) > > Perhaps if you would state your actual goal, we could judge whether this code is an effective way to accomplish it. -- DaveA
[toc] | [prev] | [next] | [standalone]
| From | Roy Smith <roy@panix.com> |
|---|---|
| Date | 2014-02-12 00:55 -0500 |
| Message-ID | <roy-11BAB5.00555912022014@news.panix.com> |
| In reply to | #65999 |
In article <mailman.6728.1392183929.18130.python-list@python.org>, Dave Angel <davea@davea.name> wrote: > Asaf Las <roegltd@gmail.com> Wrote in message: > > playing a bit with subject. > > > > pros and cons of this approach? did i create bicycle again? :-) > > > > class myclass(object): > > class_instance = None > > > > def __new__(cls, *args, **kwargs): > > if myclass.class_instance == None: > > return object.__new__(cls) > > return myclass.class_instance > > > > def __init__(self, some): > > if self.__class__.class_instance == None: # init blocker > > self.__class__.class_instance = self > > self.member = some > > > > def __del__(self): > > self.__class__.class_instance = None > > > > one_class = myclass(1) > > print(id(one_class), one_class.member ) > > > > two_class = myclass(2) > > print(id(two_class), two_class.member) > > > > > > Perhaps if you would state your actual goal, we could judge > whether this code is an effective way to accomplish > it. It looks to me like he's trying to implement a classic Gang of Four singleton pattern.
[toc] | [prev] | [next] | [standalone]
| From | Gregory Ewing <greg.ewing@canterbury.ac.nz> |
|---|---|
| Date | 2014-02-12 23:04 +1300 |
| Message-ID | <bm0v9iFpuquU1@mid.individual.net> |
| In reply to | #66000 |
Roy Smith wrote: > It looks to me like he's trying to implement a classic Gang of Four > singleton pattern. Which I've never really seen the point of in Python, or any other language for that matter. Just create one instance of the class during initialisation, put it in a global somewhere, and use it thereafter. If you really want to make sure nobody creates another instance by accident, delete the class out of the namespace after instantiating it. -- Greg
[toc] | [prev] | [next] | [standalone]
| From | Ben Finney <ben+python@benfinney.id.au> |
|---|---|
| Date | 2014-02-12 21:09 +1100 |
| Message-ID | <mailman.6750.1392199807.18130.python-list@python.org> |
| In reply to | #66022 |
Gregory Ewing <greg.ewing@canterbury.ac.nz> writes: > Roy Smith wrote: > > It looks to me like he's trying to implement a classic Gang of Four > > singleton pattern. > > Which I've never really seen the point of in Python, or any other > language for that matter. Just create one instance of the class during > initialisation, put it in a global somewhere, and use it thereafter. Make that “somewhere” a module namespace, and you effectively have a Singleton for all practical purposes. So yes, I see the point of it; but we already have it built in :-) -- \ “To save the world requires faith and courage: faith in reason, | `\ and courage to proclaim what reason shows to be true.” | _o__) —Bertrand Russell | Ben Finney
[toc] | [prev] | [next] | [standalone]
| From | Roy Smith <roy@panix.com> |
|---|---|
| Date | 2014-02-12 08:40 -0500 |
| Message-ID | <roy-828BCA.08403012022014@news.panix.com> |
| In reply to | #66024 |
In article <mailman.6750.1392199807.18130.python-list@python.org>, Ben Finney <ben+python@benfinney.id.au> wrote: > Gregory Ewing <greg.ewing@canterbury.ac.nz> writes: > > > Roy Smith wrote: > > > It looks to me like he's trying to implement a classic Gang of Four > > > singleton pattern. > > > > Which I've never really seen the point of in Python, or any other > > language for that matter. Just create one instance of the class during > > initialisation, put it in a global somewhere, and use it thereafter. > > Make that “somewhere” a module namespace, and you effectively have a > Singleton for all practical purposes. So yes, I see the point of it; but > we already have it built in :-) This is one of the big problems with the Gang of Four book (and most of the pattern literature). They present these patterns as universal to all OOPL's, when in reality, so much of them is "Things I need to do to appease the C++ compiler".
[toc] | [prev] | [next] | [standalone]
| From | Piet van Oostrum <piet@vanoostrum.org> |
|---|---|
| Date | 2014-02-13 10:00 +0100 |
| Message-ID | <m2a9dvmlos.fsf@cochabamba.vanoostrum.org> |
| In reply to | #66024 |
Ben Finney <ben+python@benfinney.id.au> writes: > Gregory Ewing <greg.ewing@canterbury.ac.nz> writes: > >> Roy Smith wrote: >> > It looks to me like he's trying to implement a classic Gang of Four >> > singleton pattern. >> >> Which I've never really seen the point of in Python, or any other >> language for that matter. Just create one instance of the class during >> initialisation, put it in a global somewhere, and use it thereafter. > > Make that “somewhere” a module namespace, and you effectively have a > Singleton for all practical purposes. So yes, I see the point of it; but > we already have it built in :-) There is a use case for a singleton class: when creating the singleton object takes considerable resources and you don't need it always in your program. -- Piet van Oostrum <piet@vanoostrum.org> WWW: http://pietvanoostrum.com/ PGP key: [8DAE142BE17999C4]
[toc] | [prev] | [next] | [standalone]
| From | Ned Batchelder <ned@nedbatchelder.com> |
|---|---|
| Date | 2014-02-13 06:50 -0500 |
| Message-ID | <mailman.6831.1392292254.18130.python-list@python.org> |
| In reply to | #66159 |
On 2/13/14 4:00 AM, Piet van Oostrum wrote: > Ben Finney <ben+python@benfinney.id.au> writes: > >> Gregory Ewing <greg.ewing@canterbury.ac.nz> writes: >> >>> Roy Smith wrote: >>>> It looks to me like he's trying to implement a classic Gang of Four >>>> singleton pattern. >>> >>> Which I've never really seen the point of in Python, or any other >>> language for that matter. Just create one instance of the class during >>> initialisation, put it in a global somewhere, and use it thereafter. >> >> Make that “somewhere” a module namespace, and you effectively have a >> Singleton for all practical purposes. So yes, I see the point of it; but >> we already have it built in :-) > > There is a use case for a singleton class: when creating the singleton > object takes considerable resources and you don't need it always in your > program. > I still don't see it. To convince me that a singleton class makes sense, you'd have to explain why by virtue of the class's very nature, it never makes sense for there ever to be more than one of them. Your example is an expensive-to-create object. Why does that mean I might not want two of them? I can see how it makes sense to have a factory function, which will make one only when asked, and will hold onto that object for the next time it's needed. But that's different than a class which pretends to make instances but actually always returns the same instance. -- Ned Batchelder, http://nedbatchelder.com
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2014-02-13 22:57 +1100 |
| Message-ID | <mailman.6834.1392292646.18130.python-list@python.org> |
| In reply to | #66159 |
On Thu, Feb 13, 2014 at 10:50 PM, Ned Batchelder <ned@nedbatchelder.com> wrote: > I still don't see it. To convince me that a singleton class makes sense, > you'd have to explain why by virtue of the class's very nature, it never > makes sense for there ever to be more than one of them. There's a huge difference, btw, between mutable and immutable singletons. With immutables like None, True/False, integers, strings, and tuples thereof, returning a preexisting object is just an optimization. Do it if you want, don't if you don't, nobody's going to hugely care. With mutables, it's hugely different. A singleton "database connection" object would, imo, be hugely confusing; you'd think you created a separate connection object, but no, what you do on this one affects the other. Better there to have module-level functions; at least Python programmers should understand that reimporting a module gives you back another reference to the same module. ChrisA
[toc] | [prev] | [next] | [standalone]
| From | Roy Smith <roy@panix.com> |
|---|---|
| Date | 2014-02-13 10:24 -0500 |
| Message-ID | <roy-141A69.10240713022014@news.panix.com> |
| In reply to | #66170 |
In article <mailman.6834.1392292646.18130.python-list@python.org>, Chris Angelico <rosuav@gmail.com> wrote: > On Thu, Feb 13, 2014 at 10:50 PM, Ned Batchelder <ned@nedbatchelder.com> > wrote: > > I still don't see it. To convince me that a singleton class makes sense, > > you'd have to explain why by virtue of the class's very nature, it never > > makes sense for there ever to be more than one of them. > > There's a huge difference, btw, between mutable and immutable > singletons. With immutables like None, True/False, integers, strings, > and tuples thereof, returning a preexisting object is just an > optimization. Do it if you want, don't if you don't, nobody's going to > hugely care. People *depend* on None being a singleton (and are encouraged to do so), when they use "is" as the test-for-Noneness. > With mutables, it's hugely different. A singleton > "database connection" object would, imo, be hugely confusing; you'd > think you created a separate connection object, but no, what you do on > this one affects the other. Except that if you do caching in the database connector, you would certainly want the cache to be shared between all the users. There's no right answer here. Each way has it's advantages and disadvantages. And it would only be confusing if the documentation didn't spell out which way it was doing it, leaving people to make (possibly wrong) assumptions. > Better there to have module-level functions; at least Python > programmers should understand that reimporting a module gives you > back another reference to the same module. Except when it doesn't. Singleton-ness of modules depends on the names under which they were imported. Symlinks, for example, can fool the import machinery. $ ls -l s1 s2 lrwxrwxrwx 1 roy roy 1 Feb 13 10:13 s1 -> s lrwxrwxrwx 1 roy roy 1 Feb 13 10:13 s2 -> s $ ls -l s total 12 -rw-rw-r-- 1 roy roy 0 Feb 13 10:13 __init__.py -rw-rw-r-- 1 roy roy 101 Feb 13 10:14 __init__.pyc -rw-rw-r-- 1 roy roy 9 Feb 13 10:12 singleton.py -rw-rw-r-- 1 roy roy 123 Feb 13 10:14 singleton.pyc >>> import s1.singleton >>> import s2.singleton >>> s1.singleton == s2.singleton False
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2014-02-14 07:03 +1100 |
| Message-ID | <mailman.6869.1392321827.18130.python-list@python.org> |
| In reply to | #66185 |
On Fri, Feb 14, 2014 at 2:24 AM, Roy Smith <roy@panix.com> wrote:
> In article <mailman.6834.1392292646.18130.python-list@python.org>,
> Chris Angelico <rosuav@gmail.com> wrote:
>
>> On Thu, Feb 13, 2014 at 10:50 PM, Ned Batchelder <ned@nedbatchelder.com>
>> wrote:
>> > I still don't see it. To convince me that a singleton class makes sense,
>> > you'd have to explain why by virtue of the class's very nature, it never
>> > makes sense for there ever to be more than one of them.
>>
>> There's a huge difference, btw, between mutable and immutable
>> singletons. With immutables like None, True/False, integers, strings,
>> and tuples thereof, returning a preexisting object is just an
>> optimization. Do it if you want, don't if you don't, nobody's going to
>> hugely care.
>
> People *depend* on None being a singleton (and are encouraged to do so),
> when they use "is" as the test-for-Noneness.
Circular argument, though. If None weren't a singleton, people would
use == to test for Noneness. Since it's been guaranteed to be
optimized to a singleton, the comparison can also be optimized, but
it's still just an optimization, as can be seen with integers. In
CPython, you could test for small integer equality using 'is', but
since that optimization isn't guaranteed, neither is that code
pattern.
>> With mutables, it's hugely different. A singleton
>> "database connection" object would, imo, be hugely confusing; you'd
>> think you created a separate connection object, but no, what you do on
>> this one affects the other.
>
> Except that if you do caching in the database connector, you would
> certainly want the cache to be shared between all the users. There's no
> right answer here. Each way has it's advantages and disadvantages. And
> it would only be confusing if the documentation didn't spell out which
> way it was doing it, leaving people to make (possibly wrong) assumptions.
Compare these:
# Style 1:
import magicsql
import othermodule
conn = magicsql.MagicSQL("127.0.0.1")
conn.set_parameter("foobar", True)
othermodule.do_stuff()
conn.query("select foo from bar")
# Style 2:
import magicsql
import othermodule
magicsql.connect("127.0.0.1")
magicsql.set_parameter("foobar", True)
othermodule.do_stuff()
magicsql.query("select foo from bar")
Suppose othermodule.do_stuff() does the same sort of calls except that
it sets parameter foobar to False. With Style 1, I would expect that
conn is independent of any connection object used by othermodule, and
it would be a major source of bugs (look at PHP's persistent
connections and how extremely careful you have to be with changing
*any* connection settings). But with Style 2, it's obvious that anyone
else importing magicsql and changing parameters will affect me.
That's why module-level functions are the clearer way to do this than
singleton classes.
>> Better there to have module-level functions; at least Python
>> programmers should understand that reimporting a module gives you
>> back another reference to the same module.
>
> Except when it doesn't. Singleton-ness of modules depends on the names
> under which they were imported. Symlinks, for example, can fool the
> import machinery.
>
> $ ls -l s1 s2
> lrwxrwxrwx 1 roy roy 1 Feb 13 10:13 s1 -> s
> lrwxrwxrwx 1 roy roy 1 Feb 13 10:13 s2 -> s
>
> $ ls -l s
> total 12
> -rw-rw-r-- 1 roy roy 0 Feb 13 10:13 __init__.py
> -rw-rw-r-- 1 roy roy 101 Feb 13 10:14 __init__.pyc
> -rw-rw-r-- 1 roy roy 9 Feb 13 10:12 singleton.py
> -rw-rw-r-- 1 roy roy 123 Feb 13 10:14 singleton.pyc
>
>>>> import s1.singleton
>>>> import s2.singleton
>>>> s1.singleton == s2.singleton
> False
Sure, they're not a guarantee. And if you fork a subprocess, then you
have copies of the singleton, too. That's not the point here. If you
have two modules and each one types "import random", you would not be
surprised to learn that the name "random" in each is bound to the
exact same random, and that they effectively share state. If you're
calling random.random(), and then you call another module which
imports random and calls random.random(), you don't complain that your
sequence of random numbers was disrupted.
But if you were to get yourself a random.Random() instance and someone
else does the same, then the style of code makes it *look like* you
should be working with independent objects. And in the case of the
random module, that is exactly what happens. Instantiate? Separate.
Module-level functions? Shared.
ChrisA
[toc] | [prev] | [next] | [standalone]
| From | Robert Kern <robert.kern@gmail.com> |
|---|---|
| Date | 2014-02-13 21:13 +0000 |
| Message-ID | <mailman.6885.1392326014.18130.python-list@python.org> |
| In reply to | #66185 |
On 2014-02-13 20:03, Chris Angelico wrote: > On Fri, Feb 14, 2014 at 2:24 AM, Roy Smith <roy@panix.com> wrote: >> In article <mailman.6834.1392292646.18130.python-list@python.org>, >> Chris Angelico <rosuav@gmail.com> wrote: >> >>> On Thu, Feb 13, 2014 at 10:50 PM, Ned Batchelder <ned@nedbatchelder.com> >>> wrote: >>>> I still don't see it. To convince me that a singleton class makes sense, >>>> you'd have to explain why by virtue of the class's very nature, it never >>>> makes sense for there ever to be more than one of them. >>> >>> There's a huge difference, btw, between mutable and immutable >>> singletons. With immutables like None, True/False, integers, strings, >>> and tuples thereof, returning a preexisting object is just an >>> optimization. Do it if you want, don't if you don't, nobody's going to >>> hugely care. >> >> People *depend* on None being a singleton (and are encouraged to do so), >> when they use "is" as the test-for-Noneness. > > Circular argument, though. If None weren't a singleton, people would > use == to test for Noneness. Since it's been guaranteed to be > optimized to a singleton, the comparison can also be optimized, but > it's still just an optimization, as can be seen with integers. In > CPython, you could test for small integer equality using 'is', but > since that optimization isn't guaranteed, neither is that code > pattern. We don't use `is None` instead of `== None` for the speed. We use it for robustness. We don't want arbitrary __eq__()s to interfere with our sentinel tests. If None weren't a singleton that we could use as such a sentinel, we'd make one. -- Robert Kern "I have come to believe that the whole world is an enigma, a harmless enigma that is made terrible by our own mad attempt to interpret it as though it had an underlying truth." -- Umberto Eco
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2014-02-14 08:27 +1100 |
| Message-ID | <mailman.6890.1392326879.18130.python-list@python.org> |
| In reply to | #66185 |
On Fri, Feb 14, 2014 at 8:13 AM, Robert Kern <robert.kern@gmail.com> wrote:
> We don't use `is None` instead of `== None` for the speed. We use it for
> robustness. We don't want arbitrary __eq__()s to interfere with our sentinel
> tests. If None weren't a singleton that we could use as such a sentinel,
> we'd make one.
Sure. Yes, its identity is important as part of its being the Python
equivalent of C's null pointer. But the main point of singletons is to
be able to be "instantiated" without creating new elements; the
sentinel status of None is no different from the classic way of
recognizing the presence of an argument:
_SENTINEL = object()
def foo(arg1, arg2=_SENTINEL):
if arg2 is not _SENTINEL: do_stuff_with(arg2)
That's not a singleton in that sense; it's just a unique object. You
could use [] for that instead of object() and it would work just the
same. So None is serving multiple purposes: it's an empty object, but
it's also a sentinel. In many uses, it wouldn't be a problem to have
more Nones floating around, hence it's mostly like your classic
singleton.
My main point about mutable vs immutable is more clearly seen with
integers and strings. Some integers are cached; some strings are
interned; nobody particularly cares about the exact boundaries, except
when playing around with id() or introspection of some sort.
ChrisA
[toc] | [prev] | [next] | [standalone]
| From | Ethan Furman <ethan@stoneleaf.us> |
|---|---|
| Date | 2014-02-13 08:57 -0800 |
| Message-ID | <mailman.6850.1392313443.18130.python-list@python.org> |
| In reply to | #66159 |
On 02/13/2014 03:50 AM, Ned Batchelder wrote: > On 2/13/14 4:00 AM, Piet van Oostrum wrote: >> Ben Finney <ben+python@benfinney.id.au> writes: >> >>> Gregory Ewing <greg.ewing@canterbury.ac.nz> writes: >>> >>>> Roy Smith wrote: >>>>> It looks to me like he's trying to implement a classic Gang of Four >>>>> singleton pattern. >>>> >>>> Which I've never really seen the point of in Python, or any other >>>> language for that matter. Just create one instance of the class during >>>> initialisation, put it in a global somewhere, and use it thereafter. >>> >>> Make that “somewhere” a module namespace, and you effectively have a >>> Singleton for all practical purposes. So yes, I see the point of it; but >>> we already have it built in :-) >> >> There is a use case for a singleton class: when creating the singleton >> object takes considerable resources and you don't need it always in your >> program. >> > > I still don't see it. To convince me that a singleton class makes sense, you'd have to explain why by virtue of the > class's very nature, it never makes sense for there ever to be more than one of them. Say you have a database with a column that can only have a handful of values (like an enumeration, for instance) and this database can have hundreds of thousands of rows. When you're working with all those rows at once having just one object for the third enum value is a useful optimization. Say you have a class that represents serial ports or your computer. You should get the same object every time you ask for SerialPort(2). -- ~Ethan~
[toc] | [prev] | [next] | [standalone]
| From | Roy Smith <roy@panix.com> |
|---|---|
| Date | 2014-02-13 12:57 -0500 |
| Message-ID | <roy-640027.12574313022014@news.panix.com> |
| In reply to | #66194 |
In article <mailman.6850.1392313443.18130.python-list@python.org>, Ethan Furman <ethan@stoneleaf.us> wrote: > Say you have a class that represents serial ports or your computer. You > should get the same object every time you ask > for SerialPort(2). Why? Certainly, you should get objects which refer to the same physical port. So: port_a = SerialPort(2) port_b = SerialPort(2) port_a.enable() assert port_b.is_shutdown() == False port_a.shutdown() assert port_b.is_shutdown() == True But, why do they have to be the same object? Why should I care if port_a is port_b is False, as long as all operations I perform on either are reflected in correct state changes on the other one?
[toc] | [prev] | [next] | [standalone]
| From | Ethan Furman <ethan@stoneleaf.us> |
|---|---|
| Date | 2014-02-13 10:31 -0800 |
| Message-ID | <mailman.6852.1392317509.18130.python-list@python.org> |
| In reply to | #66197 |
On 02/13/2014 09:57 AM, Roy Smith wrote: > In article <mailman.6850.1392313443.18130.python-list@python.org>, > Ethan Furman <ethan@stoneleaf.us> wrote: > >> Say you have a class that represents serial ports or your computer. You >> should get the same object every time you ask >> for SerialPort(2). > > Why? Certainly, you should get objects which refer to the same physical > port. So: > > port_a = SerialPort(2) > port_b = SerialPort(2) > > port_a.enable() > assert port_b.is_shutdown() == False > > port_a.shutdown() > assert port_b.is_shutdown() == True > > But, why do they have to be the same object? Why should I care if > > port_a is port_b > > is False, as long as all operations I perform on either are reflected in > correct state changes on the other one? You mean use the Borg pattern instead of the Singleton pattern? As far as I can tell they are two shades of the same thing. Are there any drastic differences between the two? Besides one having many instances that share one __dict__ and the other just having one instance and one __dict__? -- ~Ethan~
[toc] | [prev] | [next] | [standalone]
| From | Roy Smith <roy@panix.com> |
|---|---|
| Date | 2014-02-13 14:03 -0500 |
| Message-ID | <roy-BA9C8D.14031413022014@news.panix.com> |
| In reply to | #66202 |
In article <mailman.6852.1392317509.18130.python-list@python.org>, Ethan Furman <ethan@stoneleaf.us> wrote: > On 02/13/2014 09:57 AM, Roy Smith wrote: > > In article <mailman.6850.1392313443.18130.python-list@python.org>, > > Ethan Furman <ethan@stoneleaf.us> wrote: > > > >> Say you have a class that represents serial ports or your computer. You > >> should get the same object every time you ask > >> for SerialPort(2). > > > > Why? Certainly, you should get objects which refer to the same physical > > port. So: > > > > port_a = SerialPort(2) > > port_b = SerialPort(2) > > > > port_a.enable() > > assert port_b.is_shutdown() == False > > > > port_a.shutdown() > > assert port_b.is_shutdown() == True > > > > But, why do they have to be the same object? Why should I care if > > > > port_a is port_b > > > > is False, as long as all operations I perform on either are reflected in > > correct state changes on the other one? > > You mean use the Borg pattern instead of the Singleton pattern? As far as I > can tell they are two shades of the same > thing. Are there any drastic differences between the two? Besides one > having many instances that share one __dict__ > and the other just having one instance and one __dict__? I envision SerialPort being a thin layer on top of a bunch of OS-specific system calls to give them a pythonic interface. Things like is_shutdown() and set_bit_rate() presumably turn into ioctls. No need to have any state at all beyond a file descriptor.
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2014-02-14 06:50 +1100 |
| Message-ID | <mailman.6866.1392321009.18130.python-list@python.org> |
| In reply to | #66203 |
On Fri, Feb 14, 2014 at 6:03 AM, Roy Smith <roy@panix.com> wrote: > In article <mailman.6852.1392317509.18130.python-list@python.org>, > Ethan Furman <ethan@stoneleaf.us> wrote: >> >> You mean use the Borg pattern instead of the Singleton pattern? As far as I >> can tell they are two shades of the same >> thing. Are there any drastic differences between the two? Besides one >> having many instances that share one __dict__ >> and the other just having one instance and one __dict__? > > I envision SerialPort being a thin layer on top of a bunch of > OS-specific system calls to give them a pythonic interface. Things like > is_shutdown() and set_bit_rate() presumably turn into ioctls. No need > to have any state at all beyond a file descriptor. I'd go a bit further. The SerialPort instance would have its own effective state: the file descriptor. Two of them can be created and one of them closed, and the fd for that one would be closed while the other stays open. It's then two objects dealing with a common external facility. ChrisA
[toc] | [prev] | [next] | [standalone]
| From | Grant Edwards <invalid@invalid.invalid> |
|---|---|
| Date | 2014-02-13 22:28 +0000 |
| Message-ID | <ldjgtk$kgt$1@reader1.panix.com> |
| In reply to | #66203 |
On 2014-02-13, Roy Smith <roy@panix.com> wrote:
> I envision SerialPort being a thin layer on top of a bunch of
> OS-specific system calls to give them a pythonic interface.
Yep, that's pretty much what pyserial is
http://pyserial.sourceforge.net/
> Things like is_shutdown() and set_bit_rate() presumably turn into
> ioctls. No need to have any state at all beyond a file descriptor.
There are OS-dependent things that it's handy to cache in the object
(e.g. a Posix port's current termios settings). It can eliminate a
lot of ioctl() calls if the app spends a lot of time doing things like
messing with modem control lines. The savings in ioctl() calls may
not be worth worrying about, but it's actually simpler/easier to write
that way.
OTOH, caching the termios settings it can cause breakage if two
different processes or port objects are messing with the configuration
of a single port. People who do that are just begging for breakage
anyway, so they get no sympathy from me...
--
Grant Edwards grant.b.edwards Yow! I smell a RANCID
at CORN DOG!
gmail.com
[toc] | [prev] | [next] | [standalone]
Page 1 of 2 [1] 2 Next page →
Back to top | Article view | comp.lang.python
csiph-web