Making immutable instances

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Mike Meyer

    #61
    Re: Making immutable instances

    Paul Rubin <http://phr.cx@NOSPAM.i nvalid> writes:[color=blue]
    > Mike Meyer <mwm@mired.or g> writes:[color=green]
    >> When it was suggested that a facility for doing this be added to the
    >> language, I asked for a use case for it. Nobodies come up with a
    >> reason for placing such restriction on the client yet. If you've got a
    >> use case, I'd be interested in hearing it.[/color]
    > I see it the other way; almost all the time in my own code I try to
    > initialize all of any instance's attributes in an __init__ method.
    > Dynamically adding attributes is useful sometimes, but done
    > willy-nilly leads to spaghetti code.[/color]

    Pretty much anything, if abused, can lead to "spaghetti code".
    [color=blue]
    > In the cases where it's useful,
    > I'd rather see it done through a special __setattr__ method, perhaps
    > inherited from a mixin:
    >
    > class Frob(Whatsit, DynamicAttribut eMixin):
    > ...
    >
    > However, that's not likely to happen.[/color]

    The thing is, the need for an extra attribute doesn't come from your
    class, it comes from the client of your class. You can't know if the
    client code will need that facility or not, so the only choice you
    know won't be wrong sometime is to always add the mixin. In which
    case, you should follow the Python "the less boilerplate, the better"
    practice, and leave it off. Which is what we have.

    Letting the class author declare whether or not the client can add
    attributes is wrong for the same reasons - and in the same places -
    that letting the class author declare that the client shouldn't be
    allowed to access specific attributes, and so on, is wrong. Of
    course, it's also *right* for the same reasons and in the same places
    as those things. I just don't think those places happen in Python
    programs.

    <mike
    --
    Mike Meyer <mwm@mired.or g> http://www.mired.org/home/mwm/
    Independent WWW/Perforce/FreeBSD/Unix consultant, email for more information.

    Comment

    • Paul Rubin

      #62
      Re: Making immutable instances

      Mike Meyer <mwm@mired.or g> writes:[color=blue]
      > Letting the class author declare whether or not the client can add
      > attributes is wrong for the same reasons - and in the same places -
      > that letting the class author declare that the client shouldn't be
      > allowed to access specific attributes, and so on, is wrong.[/color]

      The same logic can apply to what the class operations should do. The
      answer is the same in both cases. That's why subclassing and
      inheritance were invented.

      Comment

      • bonono@gmail.com

        #63
        Re: Making immutable instances


        Mike Meyer wrote:[color=blue]
        > The thing is, the need for an extra attribute doesn't come from your
        > class, it comes from the client of your class. You can't know if the
        > client code will need that facility or not, so the only choice you
        > know won't be wrong sometime is to always add the mixin. In which
        > case, you should follow the Python "the less boilerplate, the better"
        > practice, and leave it off. Which is what we have.
        >
        > Letting the class author declare whether or not the client can add
        > attributes is wrong for the same reasons - and in the same places -
        > that letting the class author declare that the client shouldn't be
        > allowed to access specific attributes, and so on, is wrong. Of
        > course, it's also *right* for the same reasons and in the same places
        > as those things. I just don't think those places happen in Python
        > programs.
        >[/color]
        I am puzzled, and could have read what you want wrong. Are you saying
        you want something like this :

        a={}
        a.something = "I want to hang my stuff here, outside the intended use
        of dict"

        Comment

        • Mike Meyer

          #64
          Re: Making immutable instances

          Paul Rubin <http://phr.cx@NOSPAM.i nvalid> writes:[color=blue]
          > Mike Meyer <mwm@mired.or g> writes:[color=green]
          >> Letting the class author declare whether or not the client can add
          >> attributes is wrong for the same reasons - and in the same places -
          >> that letting the class author declare that the client shouldn't be
          >> allowed to access specific attributes, and so on, is wrong.[/color]
          > The same logic can apply to what the class operations should do. The
          > answer is the same in both cases. That's why subclassing and
          > inheritance were invented.[/color]

          Exactly. Adding an attribute is isomorphic to subclassing, except it
          doesn't' take any boilerplate. Unless you do something to prevent
          people from subclassing, they can always write the boilerplate and
          pretty much continue as before. I don't believe there's a good reason
          for preventing the boilerplate free method, and repeated requests for
          a use case for this have gone unsatisied.

          Have you got a use case?

          <mike
          --
          Mike Meyer <mwm@mired.or g> http://www.mired.org/home/mwm/
          Independent WWW/Perforce/FreeBSD/Unix consultant, email for more information.

          Comment

          • Mike Meyer

            #65
            Re: Making immutable instances

            bonono@gmail.co m writes:[color=blue]
            > I am puzzled, and could have read what you want wrong. Are you saying
            > you want something like this :
            >
            > a={}
            > a.something = "I want to hang my stuff here, outside the intended use
            > of dict"[/color]

            Exactly. For a use case, consider calling select.select on lists of
            file objects. If the processing is simple enough, the clearest way to
            associate a handler with each socket is just to add it as an
            attribute. But that doesn't work - sockets are bulitin types. So you
            consider less light-weight solutions, like subclassing socket (now
            that that's possible), or a dictionary of handlers keyed by socket.

            This works by default with classes written in Python. That it doesn't
            work for builtins is inconsistent, non-orthogonal, and
            incomplete. However, it's easy to work around, and the obvious fix -
            adding a dictionary to every builtin - is rather costly. So we'll live
            with it since practicality beats purity.

            <mike
            --
            Mike Meyer <mwm@mired.or g> http://www.mired.org/home/mwm/
            Independent WWW/Perforce/FreeBSD/Unix consultant, email for more information.

            Comment

            • bonono@gmail.com

              #66
              Re: Making immutable instances


              Mike Meyer wrote:[color=blue]
              > bonono@gmail.co m writes:[color=green]
              > > I am puzzled, and could have read what you want wrong. Are you saying
              > > you want something like this :
              > >
              > > a={}
              > > a.something = "I want to hang my stuff here, outside the intended use
              > > of dict"[/color]
              >
              > Exactly. For a use case, consider calling select.select on lists of
              > file objects. If the processing is simple enough, the clearest way to
              > associate a handler with each socket is just to add it as an
              > attribute. But that doesn't work - sockets are bulitin types. So you
              > consider less light-weight solutions, like subclassing socket (now
              > that that's possible), or a dictionary of handlers keyed by socket.
              >
              > This works by default with classes written in Python. That it doesn't
              > work for builtins is inconsistent, non-orthogonal, and
              > incomplete. However, it's easy to work around, and the obvious fix -
              > adding a dictionary to every builtin - is rather costly. So we'll live
              > with it since practicality beats purity.
              >[/color]
              While I agree with the use case(I want it sometimes too), it seems that
              the language creator may also deliberately disallow that, not because
              it is not doable or costly. So how, the built-in types still need to
              have some form of dictionary or else how would dir(a) of the above
              dictionary work ?

              Comment

              • Mike Meyer

                #67
                Re: Making immutable instances

                bonono@gmail.co m writes:[color=blue]
                > Mike Meyer wrote:[color=green]
                >> bonono@gmail.co m writes:[color=darkred]
                >> > I am puzzled, and could have read what you want wrong. Are you saying
                >> > you want something like this :
                >> > a={}
                >> > a.something = "I want to hang my stuff here, outside the intended use
                >> > of dict"[/color]
                >> Exactly. For a use case, consider calling select.select on lists of
                >> file objects. If the processing is simple enough, the clearest way to
                >> associate a handler with each socket is just to add it as an
                >> attribute. But that doesn't work - sockets are bulitin types. So you
                >> consider less light-weight solutions, like subclassing socket (now
                >> that that's possible), or a dictionary of handlers keyed by socket.
                >> This works by default with classes written in Python. That it doesn't
                >> work for builtins is inconsistent, non-orthogonal, and
                >> incomplete. However, it's easy to work around, and the obvious fix -
                >> adding a dictionary to every builtin - is rather costly. So we'll live
                >> with it since practicality beats purity.[/color]
                > While I agree with the use case(I want it sometimes too), it seems that
                > the language creator may also deliberately disallow that, not because
                > it is not doable or costly. So how, the built-in types still need to
                > have some form of dictionary or else how would dir(a) of the above
                > dictionary work ?[/color]

                Built-in types don't have a real dictionary. They have a C struct that
                holds the various methods. The entries in the struct are called
                "slots", hence the __slots__ magic attribute. That __slots__ makes it
                impossible to add an attribute is documented as an implementation
                detail. This makes me think that the same restriction on the builtin
                types is the same.

                FWIW, dir returns a list built from a number of source. But if you
                look at, for example, list.__dict__, you'll notice that it's not a
                dict.

                <mike
                --
                Mike Meyer <mwm@mired.or g> http://www.mired.org/home/mwm/
                Independent WWW/Perforce/FreeBSD/Unix consultant, email for more information.

                Comment

                • bonono@gmail.com

                  #68
                  Re: Making immutable instances


                  Mike Meyer wrote:[color=blue]
                  > Built-in types don't have a real dictionary. They have a C struct that
                  > holds the various methods. The entries in the struct are called
                  > "slots", hence the __slots__ magic attribute. That __slots__ makes it
                  > impossible to add an attribute is documented as an implementation
                  > detail. This makes me think that the same restriction on the builtin
                  > types is the same.
                  >
                  > FWIW, dir returns a list built from a number of source. But if you
                  > look at, for example, list.__dict__, you'll notice that it's not a
                  > dict.
                  >[/color]
                  Well, in this case, would it be simple for the OP that if he wants to
                  disallow this attaching additional things, just use __slot__.

                  What I wan to say though is, if we can live with the inability of not
                  able to attach to built-in types, why is it so difficult for other user
                  defined class ? If the authors go to the length of not allowing it, so
                  be it. They are afterall define it for their use and how someone else
                  will use it don't matter.

                  Comment

                  • Mike Meyer

                    #69
                    Re: Making immutable instances

                    bonono@gmail.co m writes:[color=blue]
                    > Well, in this case, would it be simple for the OP that if he wants to
                    > disallow this attaching additional things, just use __slot__.[/color]

                    That's *documented* as an implementation-dependent behavior. Using it
                    to get that effect is abuse of the feature, and may well quit working
                    in the future.
                    [color=blue]
                    > What I wan to say though is, if we can live with the inability of not
                    > able to attach to built-in types, why is it so difficult for other user
                    > defined class ?[/color]

                    Because not being able to do it for built-in types is an
                    implementation detail, and a wart in the language.

                    And again, *what's the use case*? A number of people have asked why we
                    shouldn't allow this, but none of them been able to come up with a use
                    case better than "I think doing that is bad style."
                    [color=blue]
                    > If the authors go to the length of not allowing it, so be it. They
                    > are afterall define it for their use and how someone else will use
                    > it don't matter.[/color]

                    I take it you never distribute your code, or otherwise expect other
                    people to reuse it?

                    <mike
                    --
                    Mike Meyer <mwm@mired.or g> http://www.mired.org/home/mwm/
                    Independent WWW/Perforce/FreeBSD/Unix consultant, email for more information.

                    Comment

                    • bonono@gmail.com

                      #70
                      Re: Making immutable instances


                      Mike Meyer wrote:[color=blue][color=green]
                      > > If the authors go to the length of not allowing it, so be it. They
                      > > are afterall define it for their use and how someone else will use
                      > > it don't matter.[/color]
                      >
                      > I take it you never distribute your code, or otherwise expect other
                      > people to reuse it?
                      >[/color]
                      No, distribute when necessary. But I define it and code it the way I
                      want, how and others will use it, curse it doesn't matter to me.

                      Of course, I would give suggestion(wish list bug as in debian term)
                      when I use other people's stuff, and see a particular usage that is not
                      there. But it ends just there, wish list.

                      Comment

                      • bonono@gmail.com

                        #71
                        Re: Making immutable instances


                        Mike Meyer wrote:[color=blue]
                        > bonono@gmail.co m writes:[color=green]
                        > > Well, in this case, would it be simple for the OP that if he wants to
                        > > disallow this attaching additional things, just use __slot__.[/color]
                        >
                        > That's *documented* as an implementation-dependent behavior. Using it
                        > to get that effect is abuse of the feature, and may well quit working
                        > in the future.
                        >[/color]
                        In this case, it seems to be fine. As the intend is just "not
                        allowing". Even it changes in the future, the worst case is just
                        "allowing", that fits your needs :-)

                        It still won't affect what is working, so it is harmless side effect,
                        if it ever changes in the future.

                        Abuse or not doesn't matter so long it fits the needs, IMO.

                        Comment

                        • bonono@gmail.com

                          #72
                          Re: Making immutable instances


                          Mike Meyer wrote:[color=blue]
                          > bonono@gmail.co m writes:[color=green]
                          > > Well, in this case, would it be simple for the OP that if he wants to
                          > > disallow this attaching additional things, just use __slot__.[/color]
                          >
                          > That's *documented* as an implementation-dependent behavior. Using it
                          > to get that effect is abuse of the feature, and may well quit working
                          > in the future.
                          >[/color]
                          I don't see it mention as implementation-dependent behaviour on this
                          page, and this is supposed to be "(for language lawyers)".

                          The official home of the Python Programming Language


                          If it really is implementation detail but not a binding to the language
                          feature, I think someone need to change the doc, at least make it more
                          clear on this page.

                          Comment

                          • bonono@gmail.com

                            #73
                            Re: Making immutable instances


                            Mike Meyer wrote:[color=blue]
                            > And again, *what's the use case*? A number of people have asked why we
                            > shouldn't allow this, but none of them been able to come up with a use
                            > case better than "I think doing that is bad style."
                            >[/color]
                            oh, that is the usual argument anyway. It is nothing but style, most of
                            the time. Making a style thing into a right/wrong, better/worse
                            argument is really for time killing, there would never be real answer.

                            Comment

                            • Mike Meyer

                              #74
                              Re: Making immutable instances

                              bonono@gmail.co m writes:[color=blue]
                              > Mike Meyer wrote:[color=green]
                              >> bonono@gmail.co m writes:[color=darkred]
                              >> > Well, in this case, would it be simple for the OP that if he wants to
                              >> > disallow this attaching additional things, just use __slot__.[/color]
                              >> That's *documented* as an implementation-dependent behavior. Using it
                              >> to get that effect is abuse of the feature, and may well quit working
                              >> in the future.[/color]
                              > It still won't affect what is working, so it is harmless side effect,
                              > if it ever changes in the future.[/color]

                              If not allowing is required, then allowing is "not working", pretty
                              much by definition.
                              [color=blue]
                              > Abuse or not doesn't matter so long it fits the needs, IMO.[/color]

                              I guess it doesn't matter to you whether or not your code works in the
                              future. It does to me.

                              <mike
                              --
                              Mike Meyer <mwm@mired.or g> http://www.mired.org/home/mwm/
                              Independent WWW/Perforce/FreeBSD/Unix consultant, email for more information.

                              Comment

                              • bonono@gmail.com

                                #75
                                Re: Making immutable instances


                                Mike Meyer wrote:[color=blue]
                                > bonono@gmail.co m writes:[color=green]
                                > > Mike Meyer wrote:[color=darkred]
                                > >> bonono@gmail.co m writes:
                                > >> > Well, in this case, would it be simple for the OP that if he wants to
                                > >> > disallow this attaching additional things, just use __slot__.
                                > >> That's *documented* as an implementation-dependent behavior. Using it
                                > >> to get that effect is abuse of the feature, and may well quit working
                                > >> in the future.[/color]
                                > > It still won't affect what is working, so it is harmless side effect,
                                > > if it ever changes in the future.[/color]
                                >
                                > If not allowing is required, then allowing is "not working", pretty
                                > much by definition.
                                >[color=green]
                                > > Abuse or not doesn't matter so long it fits the needs, IMO.[/color]
                                >
                                > I guess it doesn't matter to you whether or not your code works in the
                                > future. It does to me.
                                >[/color]
                                For this particular case, I don't see it as a problem.

                                First it meets the need, works on 2.2, 2.3, 2.4. No one knows what
                                would change in the future, beside the fact that I don't see it as
                                implementation-dependent in the doc.

                                Adding to the fact that things can/may be removed even it is fully
                                documented, without this caveat emptor(like the famous reduce/map
                                etc.). That is if I read the document when I was writing python codes
                                in the early days and used reduce/map/filter/lambda, my code still
                                breaks if in one day those are removed and I can't forsee that either.

                                So why bother, unless it has some definitive schedule(like saying in
                                2.5, reduce won't be there or __slot__ behaviour will definitely
                                change), then I would consider if the code I write now should avoid
                                using it.

                                And back to this case, I regard it as a no harm side effect, yes, it
                                doesn't perform as expected(assume it really is changed in some unknown
                                version in the future) that someone does hang something there, it
                                doesn't hurt my expected usage of the class, as this is used to prevent
                                unexpected usage.

                                Quoting the frequently used term "Practicali ty beats purity". If I have
                                a practical problem/needs now and it solves it, why not use it ?

                                The zip(it,it) case is even worse than this __slot__ situation and I
                                don't have much problem in using that either. It is not unusual in this
                                industry that certain software only expects to be working with some
                                combination of OS/Compiler version.

                                Comment

                                Working...