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


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

should "self" be changed?

Started byzipher <dreamingforward@gmail.com>
First post2015-05-26 09:37 -0700
Last post2015-05-27 15:17 +1000
Articles 20 on this page of 48 — 21 participants

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


Contents

  should "self" be changed? zipher <dreamingforward@gmail.com> - 2015-05-26 09:37 -0700
    Re: should "self" be changed? Laura Creighton <lac@openend.se> - 2015-05-26 18:57 +0200
      Re: should "self" be changed? zipher <dreamingforward@gmail.com> - 2015-05-26 20:01 -0700
      Re: should "self" be changed? zipher <dreamingforward@gmail.com> - 2015-05-26 20:15 -0700
    Re: should "self" be changed? Laurent Pointal <laurent.pointal@free.fr> - 2015-05-26 18:59 +0200
    Re: should "self" be changed? Mark Lawrence <breamoreboy@yahoo.co.uk> - 2015-05-26 18:28 +0100
      Re: should "self" be changed? zipher <dreamingforward@gmail.com> - 2015-05-26 19:48 -0700
        Re: should "self" be changed? zipher <dreamingforward@gmail.com> - 2015-05-26 20:17 -0700
          Re: should "self" be changed? Ben Finney <ben+python@benfinney.id.au> - 2015-05-27 14:39 +1000
            Re: should "self" be changed? Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2015-05-27 15:47 +1000
              Re: should "self" be changed? Ben Finney <ben+python@benfinney.id.au> - 2015-05-27 21:29 +1000
                Re: should "self" be changed? zipher <dreamingforward@gmail.com> - 2015-05-27 05:40 -0700
                  Re: should "self" be changed? Todd <toddrjen@gmail.com> - 2015-05-27 15:00 +0200
                    Re: should "self" be changed? Grant Edwards <invalid@invalid.invalid> - 2015-05-27 14:19 +0000
                    Re: should "self" be changed? zipher <dreamingforward@gmail.com> - 2015-05-30 16:18 -0700
              Re: should "self" be changed? zipher <dreamingforward@gmail.com> - 2015-05-30 16:10 -0700
            Re: should "self" be changed? zipher <dreamingforward@gmail.com> - 2015-05-30 16:13 -0700
    Re: should "self" be changed? Chris Angelico <rosuav@gmail.com> - 2015-05-27 03:31 +1000
    Re: should "self" be changed? random832@fastmail.us - 2015-05-26 14:11 -0400
    Re: should "self" be changed? Marko Rauhamaa <marko@pacujo.net> - 2015-05-26 22:46 +0300
      Re: should "self" be changed? Ned Batchelder <ned@nedbatchelder.com> - 2015-05-26 13:04 -0700
        Re: should "self" be changed? Marko Rauhamaa <marko@pacujo.net> - 2015-05-26 23:36 +0300
          Re: should "self" be changed? Anssi Saari <as@sci.fi> - 2015-05-28 17:07 +0300
            Re: should "self" be changed? Marko Rauhamaa <marko@pacujo.net> - 2015-05-28 18:01 +0300
              Re: should "self" be changed? Ian Kelly <ian.g.kelly@gmail.com> - 2015-05-28 09:40 -0600
                Re: should "self" be changed? Marko Rauhamaa <marko@pacujo.net> - 2015-05-28 19:59 +0300
                  Re: should "self" be changed? Chris Angelico <rosuav@gmail.com> - 2015-05-29 03:06 +1000
                  Re: should "self" be changed? zipher <dreamingforward@gmail.com> - 2015-05-30 16:39 -0700
              Re: should "self" be changed? Steven D'Aprano <steve@pearwood.info> - 2015-05-29 12:00 +1000
                Re: should "self" be changed? Steven D'Aprano <steve@pearwood.info> - 2015-05-29 15:46 +1000
                Re: should "self" be changed? Steven D'Aprano <steve@pearwood.info> - 2015-06-03 02:50 +1000
                  Re: should "self" be changed? "Dr. BigCock" <dreamingforward@gmail.com> - 2015-06-02 10:16 -0700
                  Re: should "self" be changed? Marko Rauhamaa <marko@pacujo.net> - 2015-06-02 20:19 +0300
                    Re: should "self" be changed? "Dr. Bigcock" <dreamingforward@gmail.com> - 2015-06-02 11:02 -0700
                    Re: should "self" be changed? Ian Kelly <ian.g.kelly@gmail.com> - 2015-06-02 19:39 -0600
                    Re: should "self" be changed? Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2015-06-03 17:05 +1000
      Re: should "self" be changed? Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2015-05-27 15:20 +1000
    Re: should "self" be changed? garabik-news-2005-05@kassiopeia.juls.savba.sk - 2015-05-26 20:26 +0000
      Re: should "self" be changed? Mark Lawrence <breamoreboy@yahoo.co.uk> - 2015-05-26 21:45 +0100
        Re: should "self" be changed? Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2015-05-27 15:23 +1000
          Re: should "self" be changed? Chris Angelico <rosuav@gmail.com> - 2015-05-27 16:32 +1000
            Re: should "self" be changed? Marko Rauhamaa <marko@pacujo.net> - 2015-05-27 10:39 +0300
              Re: should "self" be changed? Chris Angelico <rosuav@gmail.com> - 2015-05-27 18:20 +1000
              Re: should "self" be changed? zipher <dreamingforward@gmail.com> - 2015-05-30 16:15 -0700
          Re: should "self" be changed? Terry Reedy <tjreedy@udel.edu> - 2015-05-27 17:59 -0400
      Re: should "self" be changed? Vito De Tullio <vito.detullio@gmail.com> - 2015-05-26 23:17 +0200
      Re: should "self" be changed? Tim Chase <python.list@tim.thechases.com> - 2015-05-26 16:10 -0500
    Re: should "self" be changed? Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2015-05-27 15:17 +1000

Page 2 of 3 — ← Prev page 1 [2] 3  Next page →


#91261

FromNed Batchelder <ned@nedbatchelder.com>
Date2015-05-26 13:04 -0700
Message-ID<9f9498a5-8291-4347-aef2-ada324bb47a7@googlegroups.com>
In reply to#91260
On Tuesday, May 26, 2015 at 3:47:20 PM UTC-4, Marko Rauhamaa wrote:
> zipher <dreamingforward@gmail.com>:
> 
> > Would it be prudent to rid the long-standing "argument" (pun
> > unintended) about self and the ulterior spellings of it, by changing
> > it into a symbol rather than a name?
> >
> > Something like:
> >
> > class MyClass(object):
> >
> >     def __init__(@):
> >         @.dummy = None
> >
> > OR, even better, getting *rid of it* in the parameter list, so it
> > stops confusing people about how many parameters a method needs, and
> > transform it into a true *operator*.
> 
> Python's practice works. However, a small problem is presented by nested
> classes:
> 
>     class Connection:
>         def __init__(self):
>             class Idle:
>                 def signal_start(self):
>                     # how to refer to the outer self
>                     :
>             :
> 
> Solutions include:
> 
> ...
>
>     class Connection:
>         def __init__(self):
>             conn = self
>             class Idle:
>                 def signal_start(self):
>                     conn.set_state(Ready)
>             :
> 
> 
> I have used the latter method recently.

I would find it much clearer to not use a nested class
at all, and instead to pass the object into the constructor:

    class Idle:
        def __init__(self, conn):
            self.conn = conn
        def signal_start(self):
            self.conn.set_state(Ready)

    class Connection:
        def __init__(self):
            something(Idle(self))

--Ned.

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


#91263

FromMarko Rauhamaa <marko@pacujo.net>
Date2015-05-26 23:36 +0300
Message-ID<87r3q3dqju.fsf@elektro.pacujo.net>
In reply to#91261
Ned Batchelder <ned@nedbatchelder.com>:

> I would find it much clearer to not use a nested class at all, and
> instead to pass the object into the constructor:

Nested classes are excellent and expressing the state pattern <URL:
http://en.wikipedia.org/wiki/State_pattern>.


Marko

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


#91371

FromAnssi Saari <as@sci.fi>
Date2015-05-28 17:07 +0300
Message-ID<vg3k2vsvlrk.fsf@coffee.modeemi.fi>
In reply to#91263
Marko Rauhamaa <marko@pacujo.net> writes:

> Ned Batchelder <ned@nedbatchelder.com>:
>
>> I would find it much clearer to not use a nested class at all, and
>> instead to pass the object into the constructor:
>
> Nested classes are excellent and expressing the state pattern <URL:
> http://en.wikipedia.org/wiki/State_pattern>.

Do you have an example of state pattern using nested classes and python?
With a quick look I didn't happen to find one in any language.

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


#91374

FromMarko Rauhamaa <marko@pacujo.net>
Date2015-05-28 18:01 +0300
Message-ID<87siagagpx.fsf@elektro.pacujo.net>
In reply to#91371
Anssi Saari <as@sci.fi>:

> Do you have an example of state pattern using nested classes and
> python? With a quick look I didn't happen to find one in any language.

Here's an sampling from my mail server:

========================================================================
class SMTPServerConnection(ServerConnection):
    #:     :     :
    #:     :     :

    def __init__(self, server, sock, domain, peer):
        super().__init__(server, sock)
        conn = self
        client_ip = peer[0]

        class STATE:
            def __str__(self):
                return self.__class__.__name__
            def handle_command(self, cmd):
                conn.log("handle_command (unexpected): {}".format(cmd))
                assert False
            def handle_bad_command(self, reason):
                conn.log("handle_bad_command (unexpected): {}".format(reason))
                assert False
            def handle_eof(self):
                conn.log("eof (unexpected)")
                assert False
            def terminate(self):
                assert False
        
        class IDLE(STATE):
            def handle_command(self, cmd):
                conn.log("handle_command: {}".format(cmd))
                verb, args = conn.split_cmd(cmd)
                if verb == b'EHLO':
                    self.process_ehlo_or_helo(
                        args,
                        "PIPELINING",
                        "SIZE {:d}".format(conn.MAX_MSG_SIZE),
                        "VRFY",
                        "EXPN",
                        "8BITMIME")
                elif verb == b'HELO':
                    self.process_ehlo_or_helo(args)
                elif verb in [ b'NOOP', b'RSET' ]:
                    conn.respond(250, "OK")
                elif verb == b'HELP':
                    conn.respond(214, "No help available")
                elif verb in [ b'VRFY', b'EXPN' ]:
                    conn.respond(550, "Access denied to you")
                elif verb == b'QUIT':
                    conn.respond(221, "{} Closing channel".format(
                            server.domain))
                    conn.shut_down()
                    conn.set_state(QUITTING)
                elif verb == b'MAIL':
                    self.handle_mail(args)
                elif verb in [ b'RCPT', b'DATA' ]:
                    conn.respond(503, "Bad sequence of commands")
                else:
                    conn.respond(500, "Command unrecognized")

            def process_ehlo_or_helo(self, args, *capabilities):
                if not args:
                    conn.respond(501, "Missing parameter")
                    return
                try:
                    # may be an IP address
                    conn.helo_domain_name = args[0].decode()
                except UnicodeError:
                    conn.respond(501, "Bad encoding in parameter")
                    return
                if conn.local_client:
                    conn.respond(250, server.domain, *capabilities)
                    conn.set_state(IDLE)
                    return
                ## todo: remove the "suspend" concept from mux
                conn.suspend()
                conn.log("authorize helo {} from {}".format(
                        conn.helo_domain_name, client_ip))
                conn.set_state(SPF_HELO)
                def callback(verdict, reason):
                    conn.state.handle_spf_verdict(
                        verdict, reason, *capabilities)
                conn.spf_query = server.spf_client.authorize_helo(
                    server.host, conn.helo_domain_name, server.family,
                    client_ip, callback, xid = id(conn))

            #:     :     :
            #:     :     :

        class SPF_HELO(STATE):
            def terminate(self):
                conn.resume()
                conn.spf_query.cancel()
                conn.close()
                if conn.timer is not None:
                    conn.timer.cancel()
                    conn.timer = None
                conn.set_state(ZOMBIE)

            def handle_spf_verdict(self, verdict, reason, *capabilities):
                conn.resume()
                conn.log("verdict {} reason {}".format(verdict, reason))
                # RFC 4408 §2.5.5 calls for leniency for SoftFail
                #if verdict in [ SPFClient.FAIL, SPFClient.SOFT_FAIL ]:
                if verdict in [ SPFClient.FAIL ]:
                    conn.respond(550, "SPF check failed: {}".format(reason))
                    conn.set_state(IDLE)
                    return
                conn.respond(250, server.domain, *capabilities)
                conn.set_state(IDLE)

        class SPF_SENDER(STATE):
            def terminate(self):
                conn.resume()
                conn.spf_query.cancel()
                conn.close()
                if conn.timer is not None:
                    conn.timer.cancel()
                    conn.timer = None
                conn.set_state(ZOMBIE)

            def handle_spf_verdict(self, verdict, reason):
                conn.resume()
                conn.log("verdict {} reason {}".format(verdict, reason))
                # RFC 4408 §2.5.5 calls for leniency for SoftFail
                #if verdict in [ SPFClient.FAIL, SPFClient.SOFT_FAIL ]:
                if verdict in [ SPFClient.FAIL ]:
                    conn.respond(550, "SPF check failed: {}".format(reason))
                    conn.set_state(IDLE)
                    return
                conn.spf_sender_verdict = verdict
                conn.spf_sender_reason = reason
                conn.respond(250, "OK")
                conn.set_state(RECIPIENTS)

        class RECIPIENTS(STATE):
            def handle_command(self, cmd):
                conn.log("handle_command: {}".format(cmd))
                verb, args = conn.split_cmd(cmd)
                if verb in [ b'EHLO', b'HELO', b'MAIL' ]:
                    conn.respond(503, "Bad sequence of commands")
                elif verb == b'NOOP':
                    conn.respond(250, "OK")
                elif verb == b'HELP':
                    conn.respond(214, "No help available")
                elif verb == b'VRFY' or verb == b'EXPN':
                    conn.respond(550, "Access denied to you")
                elif verb == b'RSET':
                    conn.set_state(IDLE)
                    conn.respond(250, "OK")
                elif verb == b'QUIT':
                    conn.respond(221, "{} Closing channel".format(
                            server.domain))
                    conn.shut_down()
                    conn.set_state(QUITTING)
                elif verb == b'RCPT':
                    self.handle_rcpt(args)
                elif verb == b'DATA':
                    self.handle_data(args)
                else:
                    conn.respond(500, "Command unrecognized")

            #:     :     :
            #:     :     :

        self.send(("220 {} Service ready\r\n".format(domain)).encode())
        self.timer = self.mux.after(self.SERVER_TIMEOUT, self.handle_timeout)
        #:     :     :
        #:     :     :
        self.state = IDLE()

    def set_state(self, state):
        new_state = state()
        self.log("set_state: {} -> {}".format(self.state, new_state))
        self.state = new_state

    def handle_command(self, cmd):
        self.state.handle_command(cmd)

    def handle_timeout(self):
        if self.timer is None:
            return
        self.timer = None
        self.log("timeout")
        self.state.terminate()

    def handle_spf_verdict(self, verdict, reason, *capabilities):
        self.state.handle_spf_verdict(verdict, reason, *capabilities)

    #:     :     :
    #:     :     :
========================================================================


Marko

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


#91376

FromIan Kelly <ian.g.kelly@gmail.com>
Date2015-05-28 09:40 -0600
Message-ID<mailman.135.1432827676.5151.python-list@python.org>
In reply to#91374
On Thu, May 28, 2015 at 9:01 AM, Marko Rauhamaa <marko@pacujo.net> wrote:
> Anssi Saari <as@sci.fi>:
>
>> Do you have an example of state pattern using nested classes and
>> python? With a quick look I didn't happen to find one in any language.
>
> Here's an sampling from my mail server:

I think I would be more inclined to use enums. This has the advantages
of not creating a new set of state classes for every connection
instance and that each state is a singleton instance, allowing things
like "if self.state is SMTPConnectionState.IDLE". It could look
something like this:

class SMTPConnectionState(Enum):

    class IDLE:
        @classmethod
        def handle_command(cls, conn, cmd):
            # ...

    class SPF_HELO:
        @classmethod
        def terminate(cls, conn):
            # ...

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


#91378

FromMarko Rauhamaa <marko@pacujo.net>
Date2015-05-28 19:59 +0300
Message-ID<87oal4d4es.fsf@elektro.pacujo.net>
In reply to#91376
Ian Kelly <ian.g.kelly@gmail.com>:

> On Thu, May 28, 2015 at 9:01 AM, Marko Rauhamaa <marko@pacujo.net> wrote:
>> Anssi Saari <as@sci.fi>:
>>
>>> Do you have an example of state pattern using nested classes and
>>> python? With a quick look I didn't happen to find one in any
>>> language.
>>
>> Here's an sampling from my mail server:
>
> I think I would be more inclined to use enums. This has the advantages
> of not creating a new set of state classes for every connection
> instance and that each state is a singleton instance, allowing things
> like "if self.state is SMTPConnectionState.IDLE". It could look
> something like this:
>
> class SMTPConnectionState(Enum):
>
>     class IDLE:
>         @classmethod
>         def handle_command(cls, conn, cmd):
>             # ...
>
>     class SPF_HELO:
>         @classmethod
>         def terminate(cls, conn):
>             # ...

Really, the main expressive choice is whether you use an inner class
(and get the advantages of a closure) or an outer class (and get
potential performance advantages).

When I have coded state machines for C or Java, I have noticed that
nothing beats enums and switch statements performance-wise, and
expressively, they're not that bad, either. Python doesn't have a switch
statement, so the natural thing is to ride on method dispatching
(whether via inner or outer classes). However, I must say the exception
"idiom" someone mentioned on this forum way back has its lure:

    try: raise self.state
    except IDLE:
        #...
    except SPF_HELO:
        #...


Marko

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


#91379

FromChris Angelico <rosuav@gmail.com>
Date2015-05-29 03:06 +1000
Message-ID<mailman.136.1432832766.5151.python-list@python.org>
In reply to#91378
On Fri, May 29, 2015 at 2:59 AM, Marko Rauhamaa <marko@pacujo.net> wrote:
> When I have coded state machines for C or Java, I have noticed that
> nothing beats enums and switch statements performance-wise, and
> expressively, they're not that bad, either. Python doesn't have a switch
> statement, so the natural thing is to ride on method dispatching
> (whether via inner or outer classes). However, I must say the exception
> "idiom" someone mentioned on this forum way back has its lure:
>
>     try: raise self.state
>     except IDLE:
>         #...
>     except SPF_HELO:
>         #...

I take exception to that idiom. :)

ChrisA

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


#91553

Fromzipher <dreamingforward@gmail.com>
Date2015-05-30 16:39 -0700
Message-ID<81b3cc36-0f43-4f03-8319-1eb42ffe21d9@googlegroups.com>
In reply to#91378
On Thursday, May 28, 2015 at 11:59:36 AM UTC-5, Marko Rauhamaa wrote:
> Ian Kelly <ian.g.kelly@gmail.com>:
> > I think I would be more inclined to use enums. This has the advantages
> > of not creating a new set of state classes for every connection
> > instance and that each state is a singleton instance, allowing things
> > like "if self.state is SMTPConnectionState.IDLE". It could look
> > something like this:
> >
> > class SMTPConnectionState(Enum):
> >
> >     class IDLE:
> >         @classmethod
> >         def handle_command(cls, conn, cmd):
> >             # ...
> >
> >     class SPF_HELO:
> >         @classmethod
> >         def terminate(cls, conn):
> >             # ...
> 
> Really, the main expressive choice is whether you use an inner class
> (and get the advantages of a closure) or an outer class (and get
> potential performance advantages).

Can you tell me: What is the advantage of a closure here?

Also:  why wouldn't you simply put your state classes at the outer scope (i.e. module-level) of your module so that they are clear to anyone else who want to use the module?  Presumably these classes are for making your SMTPServerConnection object more useable, not to hide these state-classes from the users.

MarkJ

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


#91416

FromSteven D'Aprano <steve@pearwood.info>
Date2015-05-29 12:00 +1000
Message-ID<5567c840$0$12998$c3e8da3$5496439d@news.astraweb.com>
In reply to#91374
On Fri, 29 May 2015 01:01 am, Marko Rauhamaa wrote:

> Anssi Saari <as@sci.fi>:
> 
>> Do you have an example of state pattern using nested classes and
>> python? With a quick look I didn't happen to find one in any language.
> 
> Here's an sampling from my mail server:


I haven't studied this in close detail, but first impressions is that this
is not well-written Python code. The obvious problems that come to mind:


> class SMTPServerConnection(ServerConnection):
>     #:     :     :
>     #:     :     :
> 
>     def __init__(self, server, sock, domain, peer):
>         super().__init__(server, sock)
>         conn = self
>         client_ip = peer[0]
> 
>         class STATE:
>             def __str__(self):
>                 return self.__class__.__name__

A minor criticism: each time you instantiate a new SMTP server connection,
it creates new STATE, IDLE etc. classes. That's wasteful and inefficient
unless you have a good reason for it, although you may not care if you only
have a single connection at a time.

More serious problem: by nesting the state classes, it is much harder to
test the state classes in isolation from a connection.


>             def handle_command(self, cmd):
>                 conn.log("handle_command (unexpected): {}".format(cmd))
>                 assert False

At first glance, this appears to be an abuse of `assert` and risks breaking
your code when running under -O which turns debugging (and hence asserts)
off. Since the intent is to make these abstract methods which must be
overridden, I'd prefer to define an AbstractMethodError, then:

    raise AbstractMethodError("unexpected %s" % cmd)

then do the logging elsewhere.

This has the advantage(?) of eliminating the need to refer to conn, which
means that the methods are no longer closures and the entire inner class
can be moved out of the SMTPServerConnection body.

[...]
>         class IDLE(STATE):
>             def handle_command(self, cmd):
>                 conn.log("handle_command: {}".format(cmd))

Using a closure for information hiding is a solid functional equivalent to
using private fields in an OOP context. However, "private" should be
considered an anti-testing idiom. I would seriously consider this entire
design to be an anti-pattern, and would prefer to one of two alternate
designs:

(1) Pull the state classes out of the SMTPServerConnection class. On
initialisation, each state takes a conn argument. All references to "conn"
are replaced by "self.conn". That's basically the conventional OOP
approach.

(2) Again, pull the state classes out of the SMTPServerConnection class,
except this time there is no need to instantiate the state classes at all!
Decorate all the methods with @classmethod, and have them take the
connection as an explicit argument. The caller (namely the
SMTPServerConnection  instance) provides itself as argument to the state
methods, like so:

    self.state = IDLE  # No need to instantiate.
    self.state.process_ehlo_or_helo(self, other, args, go, here)

This reduces implicit coupling, makes it explicit that the state methods
depend on the connection, avoids reference loops, and enables easy mocking
for testing.

The only downsides are that people coming from a conventional (e.g. Java)
OOP background will freak at seeing you using a class as a first class
value (pun intended), and it will be ever-so-slightly tiresome to have to
decorate each and every method with classmethod.

(Perhaps a class decorator is the solution to that second issue?)

The "design pattern" community is dominated by Java, where classes are not
values, so this idiom is impossible in Java and unlikely to have a DP name.
But it really should have one -- in a language where classes are themselves
values, there is no reason why a class *must* be instantiated, particularly
if you're only using a single instance of the class. Anyone ever come
across a named design pattern that involves using classes directly without
instantiating them?

I'm basically looking for a less inelegant term for "instanceless class" --
not so much a singleton as a zeroton.



-- 
Steven

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


#91428

FromSteven D'Aprano <steve@pearwood.info>
Date2015-05-29 15:46 +1000
Message-ID<5567fd36$0$13006$c3e8da3$5496439d@news.astraweb.com>
In reply to#91416
On Fri, 29 May 2015 12:00 pm, Steven D'Aprano wrote:

> I haven't studied this in close detail, but first impressions is that this
> is not well-written Python code. The obvious problems that come to mind:

Well, first impressions can be misleading... I wrote the above, thinking
that there were more problems with the code than there actually are.
(Specifically, I didn't notice that the inner classes used closures for
their methods, then forgot to go back and revise that sentence.) So the
code actually was not as bad as I first thought, not withstanding the
issues that I described in my previous post.



-- 
Steven

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


#91863

FromSteven D'Aprano <steve@pearwood.info>
Date2015-06-03 02:50 +1000
Message-ID<556ddef1$0$13004$c3e8da3$5496439d@news.astraweb.com>
In reply to#91416
On Fri, 29 May 2015 12:00 pm, Steven D'Aprano wrote:

[...]
> in a language where classes are 
> themselves values, there is no reason why a class must be instantiated,
> particularly if you're only using a single instance of the class. Anyone
> ever come across a named design pattern that involves using classes
> directly without instantiating them?
> 
> I'm basically looking for a less inelegant term for "instanceless class"
> -- not so much a singleton as a zeroton.

C# has these, and calls them static classes.

https://msdn.microsoft.com/en-us/library/79b3xss3%28v=vs.100%29.aspx




-- 
Steven

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


#91867

From"Dr. BigCock" <dreamingforward@gmail.com>
Date2015-06-02 10:16 -0700
Message-ID<118e319a-792e-4ca8-bcf8-7b9e60b842a2@googlegroups.com>
In reply to#91863
On Tuesday, June 2, 2015 at 11:51:10 AM UTC-5, Steven D'Aprano wrote:
> On Fri, 29 May 2015 12:00 pm, Steven D'Aprano wrote:
> 
> [...]
> > in a language where classes are 
> > themselves values, there is no reason why a class must be instantiated,
> > particularly if you're only using a single instance of the class. Anyone
> > ever come across a named design pattern that involves using classes
> > directly without instantiating them?
> > 
> > I'm basically looking for a less inelegant term for "instanceless class"
> > -- not so much a singleton as a zeroton.

The only reason to have such uninstanced classed is for meta-class programming -- where you're designing classes *programmatically*, not by your interaction and typing in your source code as you normally would.

Otherwise, I'm suspicious that "there's no reason why a class must be instantiated".  It's like declaring a complex variable and never using it.

--m

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


#91868

FromMarko Rauhamaa <marko@pacujo.net>
Date2015-06-02 20:19 +0300
Message-ID<87mw0i6n9i.fsf@elektro.pacujo.net>
In reply to#91863
Steven D'Aprano <steve@pearwood.info>:

> On Fri, 29 May 2015 12:00 pm, Steven D'Aprano wrote:
>
> [...]
>> in a language where classes are 
>> themselves values, there is no reason why a class must be instantiated,
>> particularly if you're only using a single instance of the class. Anyone
>> ever come across a named design pattern that involves using classes
>> directly without instantiating them?
>> 
>> I'm basically looking for a less inelegant term for "instanceless class"
>> -- not so much a singleton as a zeroton.
>
> C# has these, and calls them static classes.

I guess Python has them, too, and calls them modules.


Marko

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


#91872

From"Dr. Bigcock" <dreamingforward@gmail.com>
Date2015-06-02 11:02 -0700
Message-ID<1b66e0b5-639f-47e4-a0f6-cd9a96eb2fdc@googlegroups.com>
In reply to#91868
On Tuesday, June 2, 2015 at 12:20:04 PM UTC-5, Marko Rauhamaa wrote:
> Steven D'Aprano <steve@pearwood.info>:
> 
> > On Fri, 29 May 2015 12:00 pm, Steven D'Aprano wrote:
> >
> > [...]
> >> in a language where classes are 
> >> themselves values, there is no reason why a class must be instantiated,
> >> particularly if you're only using a single instance of the class. Anyone
> >> ever come across a named design pattern that involves using classes
> >> directly without instantiating them?
> >> 
> >> I'm basically looking for a less inelegant term for "instanceless class"
> >> -- not so much a singleton as a zeroton.
> >
> > C# has these, and calls them static classes.
> 
> I guess Python has them, too, and calls them modules.

Good point!
 
--m

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


#91917

FromIan Kelly <ian.g.kelly@gmail.com>
Date2015-06-02 19:39 -0600
Message-ID<mailman.89.1433295614.13271.python-list@python.org>
In reply to#91868
On Tue, Jun 2, 2015 at 11:19 AM, Marko Rauhamaa <marko@pacujo.net> wrote:
> Steven D'Aprano <steve@pearwood.info>:
>
>> On Fri, 29 May 2015 12:00 pm, Steven D'Aprano wrote:
>>
>> [...]
>>> in a language where classes are
>>> themselves values, there is no reason why a class must be instantiated,
>>> particularly if you're only using a single instance of the class. Anyone
>>> ever come across a named design pattern that involves using classes
>>> directly without instantiating them?
>>>
>>> I'm basically looking for a less inelegant term for "instanceless class"
>>> -- not so much a singleton as a zeroton.
>>
>> C# has these, and calls them static classes.
>
> I guess Python has them, too, and calls them modules.

Indeed. I find it amusing that C# has special syntax to work around
what is ostensibly a design feature -- that all code must be contained
in a class (or struct).

But then, the same practice also exists in Java, where there is no
specific syntax for it.

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


#91921

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2015-06-03 17:05 +1000
Message-ID<556ea755$0$12995$c3e8da3$5496439d@news.astraweb.com>
In reply to#91868
On Wednesday 03 June 2015 03:19, Marko Rauhamaa wrote:

> Steven D'Aprano <steve@pearwood.info>:
> 
>> On Fri, 29 May 2015 12:00 pm, Steven D'Aprano wrote:
>>
>> [...]
>>> in a language where classes are
>>> themselves values, there is no reason why a class must be instantiated,
>>> particularly if you're only using a single instance of the class. Anyone
>>> ever come across a named design pattern that involves using classes
>>> directly without instantiating them?
>>> 
>>> I'm basically looking for a less inelegant term for "instanceless class"
>>> -- not so much a singleton as a zeroton.
>>
>> C# has these, and calls them static classes.
> 
> I guess Python has them, too, and calls them modules.


Modules play a similar role -- after all, modules and classes are both 
namespaces. But:

- you can't (easily) use inheritance on a module to make a new module, 
  but you can use inheritance on a class; although I think C# prohibits
  that.

- you can't (easily) include more than one module in a single file.


-- 
Steve

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


#91281

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2015-05-27 15:20 +1000
Message-ID<5565542a$0$2796$c3e8da3$76491128@news.astraweb.com>
In reply to#91260
On Wednesday 27 May 2015 05:46, Marko Rauhamaa wrote:

> Python's practice works. However, a small problem is presented by nested
> classes:
> 
>     class Connection:
>         def __init__(self):
>             class Idle:
>                 def signal_start(self):
>                     # how to refer to the outer self
>                     :
>             :


The best solution is not to use nested classes, but if you really must:


class Connection:
    def __init__(self):
        class Idle:
            def signal_start(this):
                # this is the Idle instance;
                # self is the Connection instance



-- 
Steve

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


#91262

Fromgarabik-news-2005-05@kassiopeia.juls.savba.sk
Date2015-05-26 20:26 +0000
Message-ID<mk2kte$opk$2@speranza.aioe.org>
In reply to#91253
zipher <dreamingforward@gmail.com> wrote:
> Would it be prudent to rid the long-standing "argument" (pun
> unintended) about self and the ulterior spellings of it, by changing
> it into a symbol rather than a name?  
> 
> Something like:
> 
> class MyClass(object):
> 
>     def __init__(@):
>         @.dummy = None

Believe or not, python3 (via Guido's time machine) already anticipated 
this suggestion and you can indeed use a symbol instead of 'self':

class MyClass(object):

   def __init__(ስ):
       ስ.dummy = None

-- 
 -----------------------------------------------------------
| Radovan Garabík http://kassiopeia.juls.savba.sk/~garabik/ |
| __..--^^^--..__    garabik @ kassiopeia.juls.savba.sk     |
 -----------------------------------------------------------
Antivirus alert: file .signature infected by signature virus.
Hi! I'm a signature virus! Copy me into your signature file to help me spread!

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


#91264

FromMark Lawrence <breamoreboy@yahoo.co.uk>
Date2015-05-26 21:45 +0100
Message-ID<mailman.64.1432673145.5151.python-list@python.org>
In reply to#91262
On 26/05/2015 21:26, garabik-news-2005-05@kassiopeia.juls.savba.sk wrote:
> zipher <dreamingforward@gmail.com> wrote:
>> Would it be prudent to rid the long-standing "argument" (pun
>> unintended) about self and the ulterior spellings of it, by changing
>> it into a symbol rather than a name?
>>
>> Something like:
>>
>> class MyClass(object):
>>
>>      def __init__(@):
>>          @.dummy = None
>
> Believe or not, python3 (via Guido's time machine) already anticipated
> this suggestion and you can indeed use a symbol instead of 'self':
>
> class MyClass(object):
>
>     def __init__(ስ):
>         ስ.dummy = None
>

Apart from breaking all the tools that rely on "self" being spelt "self" 
this looks like an excellent idea.

-- 
My fellow Pythonistas, ask not what our language can do for you, ask
what you can do for our language.

Mark Lawrence

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


#91282

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2015-05-27 15:23 +1000
Message-ID<556554d9$0$2796$c3e8da3$76491128@news.astraweb.com>
In reply to#91264
On Wednesday 27 May 2015 06:45, Mark Lawrence wrote:

> Apart from breaking all the tools that rely on "self" being spelt "self"
> this looks like an excellent idea.

Tools which rely on self being spelled "self" are already broken. It's a 
convention, nothing more, and there are various good reasons for breaking 
the convention:

- metaclasses
- classmethods
- custom descriptors
- nested classes



-- 
Steve

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


Page 2 of 3 — ← Prev page 1 [2] 3  Next page →

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


csiph-web