Accessors in Python (getters and setters)

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

    Accessors in Python (getters and setters)

    Hello,

    What is the Pythonic way of implementing getters and setters. I've
    heard
    people say the use of accessors is not Pythonic. But why? And what is
    the alternative? I refrain from using them because they smell
    "Javaish."
    But now my code base is expanding and I'm beginning to appreciate the
    wisdom behind them. I welcome example code and illustrations.

    Regards

  • Lawrence Oluyede

    #2
    Re: Accessors in Python (getters and setters)

    mystilleef <mystilleef@gma il.comwrote:
    What is the Pythonic way of implementing getters and setters.
    Using public members and turning them into properties when needed
    I've
    heard
    people say the use of accessors is not Pythonic. But why?
    Because there's no need to have them everywhere
    But now my code base is expanding and I'm beginning to appreciate the
    wisdom behind them. I welcome example code and illustrations.
    Search for "python property"

    --
    Lawrence - http://www.oluyede.org/blog
    "Nothing is more dangerous than an idea
    if it's the only one you have" - E. A. Chartier

    Comment

    • Diez B. Roggisch

      #3
      Re: Accessors in Python (getters and setters)

      mystilleef wrote:
      Hello,
      >
      What is the Pythonic way of implementing getters and setters. I've
      heard
      people say the use of accessors is not Pythonic. But why? And what is
      the alternative? I refrain from using them because they smell
      "Javaish."
      But now my code base is expanding and I'm beginning to appreciate the
      wisdom behind them. I welcome example code and illustrations.
      Which wisdom do you mean? The wisdom that a language that has no property
      mechanism and thus can't intercept setting and getting of instance members
      needs a bulky convention called JAVA Beans, so that _all_ uses of
      properties are tunneled through some code, even if only a few percent of
      these actually need that?

      Or the wisdom that strangling developers by putting access modifiers with
      approx. a dozen different rules in place is an annoyance to adult
      developers to say the least?

      These are the reasons they are not pythonic. We can intercept property
      access (see the property descriptor, http://pyref.infogami.com/property),
      and we trust in developers being able to judge form themselves if messing
      with internals of code is a good idea or not.

      Regards,

      Diez



      Comment

      • mystilleef

        #4
        Re: Accessors in Python (getters and setters)

        I decided to change the name of an attribute. Problem is I've used the
        attribute in several places spanning thousands of lines of code. If I
        had encapsulated the attribute via an accessor, I wouldn't need to do
        an unreliable and tedious search and replace accross several source
        code files to achieve my goal. I could simply change the name of the
        attribute and move on. Well, I'm glad python has properties. It's a
        feature that should be advertised more, especially for large scale
        python development.

        Diez B. Roggisch wrote:
        mystilleef wrote:
        >
        Hello,

        What is the Pythonic way of implementing getters and setters. I've
        heard
        people say the use of accessors is not Pythonic. But why? And what is
        the alternative? I refrain from using them because they smell
        "Javaish."
        But now my code base is expanding and I'm beginning to appreciate the
        wisdom behind them. I welcome example code and illustrations.
        >
        Which wisdom do you mean? The wisdom that a language that has no property
        mechanism and thus can't intercept setting and getting of instance members
        needs a bulky convention called JAVA Beans, so that _all_ uses of
        properties are tunneled through some code, even if only a few percent of
        these actually need that?
        >
        Or the wisdom that strangling developers by putting access modifiers with
        approx. a dozen different rules in place is an annoyance to adult
        developers to say the least?
        >
        These are the reasons they are not pythonic. We can intercept property
        access (see the property descriptor, http://pyref.infogami.com/property),
        and we trust in developers being able to judge form themselves if messing
        with internals of code is a good idea or not.
        >
        Regards,
        >
        Diez

        Comment

        • Ant

          #5
          Re: Accessors in Python (getters and setters)


          mystilleef wrote:
          I decided to change the name of an attribute. Problem is I've used the
          attribute in several places spanning thousands of lines of code. If I
          had encapsulated the attribute via an accessor, I wouldn't need to do
          an unreliable and tedious search and replace accross several source
          code files to achieve my goal. I could simply change the name of the
          attribute and move on.
          You could, but then you'd be left with crap names for your accessors!
          In your equivalent Java code, you'd typically have used the accessors
          in several places throughout the code (or else why bother using them?),
          so you wouldn't be any better off!

          The main benefit for having accessors in Java is not that you can
          change the *name* of an attribute, but that you can change the
          implementation of the attribute - i.e. change the what actually happens
          to when the accessor is called. Which you can do in Python with
          properties.

          Comment

          • Diez B. Roggisch

            #6
            Re: Accessors in Python (getters and setters)

            mystilleef wrote:
            I decided to change the name of an attribute. Problem is I've used the
            attribute in several places spanning thousands of lines of code. If I
            had encapsulated the attribute via an accessor, I wouldn't need to do
            an unreliable and tedious search and replace accross several source
            code files to achieve my goal. I could simply change the name of the
            attribute and move on. Well, I'm glad python has properties. It's a
            feature that should be advertised more, especially for large scale
            python development.
            Ergh, I don't see how the name-changing of an attribute makes any difference
            with respect to the application of getters/setters.

            Where is the difference in searching my_attribute vs. getMyAttribute
            throughout your code?

            Or do you mean that you changed

            def getFoo(self):
            return self.foo

            to something like

            def getFoo(self):
            return self.fooSomethi ng

            ? I'd say that whatever reasoning which inspired you to change foo to
            fooSomething applies to getFoo as well.

            Regards,

            Diez

            Comment

            • Bruno Desthuilliers

              #7
              Re: Accessors in Python (getters and setters)

              mystilleef wrote:
              I decided to change the name of an attribute. Problem is I've used the
              attribute in several places spanning thousands of lines of code. If I
              had encapsulated the attribute via an accessor, I wouldn't need to do
              an unreliable and tedious search and replace
              find and grep are usually mostly reliable for this kind of tasks.
              accross several source
              code files to achieve my goal. I could simply change the name of the
              attribute and move on.
              Why did you change the name of the attribute ? If it was to better
              reflect the semantic, then it's a change in the API and getters/setters
              wouldn't have help (you'd have to do the same "tedious and unreliable"
              search/replace dance). If it's about implementation, then it was time to
              use a property - that's what they are for.

              --
              bruno desthuilliers
              python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
              p in 'onurb@xiludom. gro'.split('@')])"

              Comment

              • Jason

                #8
                Re: Accessors in Python (getters and setters)


                mystilleef wrote:
                I decided to change the name of an attribute. Problem is I've used the
                attribute in several places spanning thousands of lines of code. If I
                had encapsulated the attribute via an accessor, I wouldn't need to do
                an unreliable and tedious search and replace accross several source
                code files to achieve my goal. I could simply change the name of the
                attribute and move on. Well, I'm glad python has properties. It's a
                feature that should be advertised more, especially for large scale
                python development.
                >
                Diez B. Roggisch wrote:
                mystilleef wrote:
                Hello,
                >
                What is the Pythonic way of implementing getters and setters. I've
                heard
                people say the use of accessors is not Pythonic. But why? And what is
                the alternative? I refrain from using them because they smell
                "Javaish."
                But now my code base is expanding and I'm beginning to appreciate the
                wisdom behind them. I welcome example code and illustrations.
                Which wisdom do you mean? The wisdom that a language that has no property
                mechanism and thus can't intercept setting and getting of instance members
                needs a bulky convention called JAVA Beans, so that _all_ uses of
                properties are tunneled through some code, even if only a few percent of
                these actually need that?

                Or the wisdom that strangling developers by putting access modifiers with
                approx. a dozen different rules in place is an annoyance to adult
                developers to say the least?

                These are the reasons they are not pythonic. We can intercept property
                access (see the property descriptor, http://pyref.infogami.com/property),
                and we trust in developers being able to judge form themselves if messing
                with internals of code is a good idea or not.

                Regards,

                Diez
                The property() mechanism gets rid of the need for getters and setters,
                as you can invisibly change a member variable into a getter/setter as
                needed. Nothing else needs to know that its using a property and not a
                getter/setter.

                Nothing like being forced to write getters and setters in C++/Java
                before you feel like shooting your source code. Please don't bring
                this code-rage into Python.

                To refactor a name in your code, take a look at Bicycle Repair Man
                [http://bicyclerepair.sourceforge.net/]. It integrates into Eclipse
                via PyDev, and allows you to refactor variable names, class names, and
                method names fairly easily.

                Good luck!

                --Jason

                Comment

                • ZeD

                  #9
                  Re: Accessors in Python (getters and setters)

                  Bruno Desthuilliers wrote:
                  >I decided to change the name of an attribute. Problem is I've used the
                  >attribute in several places spanning thousands of lines of code. If I
                  >had encapsulated the attribute via an accessor, I wouldn't need to do
                  >an unreliable and tedious search and replace
                  find and grep are usually mostly reliable for this kind of tasks.
                  you mean sed :)

                  sed 's/oldName/newName/g' oldFile newFile

                  --
                  Under construction

                  Comment

                  • Bruno Desthuilliers

                    #10
                    Re: Accessors in Python (getters and setters)

                    ZeD wrote:
                    Bruno Desthuilliers wrote:
                    >
                    >
                    >>>I decided to change the name of an attribute. Problem is I've used the
                    >>>attribute in several places spanning thousands of lines of code. If I
                    >>>had encapsulated the attribute via an accessor, I wouldn't need to do
                    >>>an unreliable and tedious search and replace
                    >>
                    >>find and grep are usually mostly reliable for this kind of tasks.
                    >
                    >
                    you mean sed :)
                    No, I meant find and grep.
                    sed 's/oldName/newName/g' oldFile newFile
                    >
                    Yeah, fine - as long as your pretty sure the same name is not used in
                    other contexts in any of the source files...

                    --
                    bruno desthuilliers
                    python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
                    p in 'onurb@xiludom. gro'.split('@')])"

                    Comment

                    • mystilleef

                      #11
                      Re: Accessors in Python (getters and setters)

                      Hello,

                      Thanks for the responses. The reason I want to change the name of the
                      attribute is because it doesn't reflect the purpose of the attribute,
                      anymore. The attribute was originally a string object, but not anymore.
                      It is primarily a readability issue. There are also a few key
                      attributes I don't want developers, including myself, fiddling with.
                      Properties /accessors are good because they allow you to encapsulate
                      attributes so you can change implementations at will. Some of you have
                      argued I would have needed to change accessor names too if I had
                      misnamed them earlier. It's hard to say. I find myself changing the
                      names of attributes a lot more frequently than I do functions or
                      methods. Choosing a crappy attribute name is effortless for me,
                      especially during intense coding sessions. I usually realize I've
                      choosing a crappy attribute name the next day, sometimes even later.
                      However, I put a lot more effort into choosing method and function
                      names, especially when I know it may likely be a public API. Plus it's
                      really hard to choose crappy accessor name.

                      Regards

                      Comment

                      • Bruno Desthuilliers

                        #12
                        Re: Accessors in Python (getters and setters)

                        mystilleef wrote:
                        Hello,
                        >
                        Thanks for the responses. The reason I want to change the name of the
                        attribute is because it doesn't reflect the purpose of the attribute,
                        anymore. The attribute was originally a string object, but not anymore.
                        It is primarily a readability issue. There are also a few key
                        attributes I don't want developers, including myself, fiddling with.
                        Properties /accessors are good because they allow you to encapsulate
                        attributes so you can change implementations at will. Some of you have
                        argued I would have needed to change accessor names too if I had
                        misnamed them earlier. It's hard to say. I find myself changing the
                        names of attributes a lot more frequently than I do functions or
                        methods. Choosing a crappy attribute name is effortless for me,
                        especially during intense coding sessions. I usually realize I've
                        choosing a crappy attribute name the next day, sometimes even later.
                        However, I put a lot more effort into choosing method and function
                        names, especially when I know it may likely be a public API.
                        What you need to understand here is that in Python,
                        1/ methods *are* attributes
                        2/ every attribute whose name is not prefixed by a leading underscore is
                        considered part of the api ('__magic__' names being a special case).

                        So it has nothing to do with "data vs method" dichotomy (which makes no
                        sens in a languages where functions and methods are objects), only with
                        "API vs implementation" . You choosed a crappy name for an attribute
                        that's part of the API, so it's *exactly* the same case as if you had
                        chosen a crappy name for a public method in Java. Think of public "data"
                        attributes as magical getter/setters with the most straightforward
                        behaviour, and of properties as the way to override this default behaviour.
                        Plus it's
                        really hard to choose crappy accessor name.
                        What about getMyCrappyAttr ibuteName/setMyCrappyAttr ibuteName ?-)



                        --
                        bruno desthuilliers
                        python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
                        p in 'onurb@xiludom. gro'.split('@')])"

                        Comment

                        • mystilleef

                          #13
                          Re: Accessors in Python (getters and setters)

                          Lousy Attribute Name:
                          self.tmp

                          Accessors:
                          set_temporary_b uffer
                          get_temporary_b uffer

                          The attribute name I chose, "tmp" sucks. I have used that name in
                          dozens of places spanning over 27000 LOC. There's a chance that other
                          develops might misinterpret exactly what "tmp" does. Plus I don't want
                          emails from other developers querying me about what "tmp" is/does.
                          "tmp" is obvious to me, but not necessarily to others. Now compare that
                          to the accessors. Not only do they improve readability at the expense
                          of more code, they actually allow me to change the lousily named
                          attribute "tmp" to "temporary_buff er" without grepping, seding,
                          searching, replacing and praying. Sure, if you are dealing with less
                          than a 1000LOC you can get away with using "tmp" or renaming it easily.
                          But if you are dealing with a much larger code base and more
                          developers, issues like this rapidly become a nuisance.

                          Yes, it is possible to name crappy accessors too (e.g set_tmp/get_tmp).
                          But developers tend to pay more attention to given methods/functions
                          less crappy names, at least when compared to data attributes. This
                          stems from the fact that in many languages data attributes aren't
                          usually part of the API, as well as the whole OO(Encapsulatio n) blah
                          blah. I know I would not name the accessors set_tmp/get_tmp, because my
                          philosophy is that methods/functions need to have meaningful names and
                          state their intended purpose. I don't hold data attributes to such
                          standards and I imagine many developers don't either and least based on
                          other people's code I've read. Plus there are many occassions when
                          attributes are not intended to be APIs, but eventually become one.
                          After all most data attributes are created with the purpose of serving
                          methods.

                          Bruno Desthuilliers wrote:
                          mystilleef wrote:
                          Hello,

                          Thanks for the responses. The reason I want to change the name of the
                          attribute is because it doesn't reflect the purpose of the attribute,
                          anymore. The attribute was originally a string object, but not anymore.
                          It is primarily a readability issue. There are also a few key
                          attributes I don't want developers, including myself, fiddling with.
                          Properties /accessors are good because they allow you to encapsulate
                          attributes so you can change implementations at will. Some of you have
                          argued I would have needed to change accessor names too if I had
                          misnamed them earlier. It's hard to say. I find myself changing the
                          names of attributes a lot more frequently than I do functions or
                          methods. Choosing a crappy attribute name is effortless for me,
                          especially during intense coding sessions. I usually realize I've
                          choosing a crappy attribute name the next day, sometimes even later.
                          However, I put a lot more effort into choosing method and function
                          names, especially when I know it may likely be a public API.
                          >
                          What you need to understand here is that in Python,
                          1/ methods *are* attributes
                          2/ every attribute whose name is not prefixed by a leading underscore is
                          considered part of the api ('__magic__' names being a special case).
                          >
                          So it has nothing to do with "data vs method" dichotomy (which makes no
                          sens in a languages where functions and methods are objects), only with
                          "API vs implementation" . You choosed a crappy name for an attribute
                          that's part of the API, so it's *exactly* the same case as if you had
                          chosen a crappy name for a public method in Java. Think of public "data"
                          attributes as magical getter/setters with the most straightforward
                          behaviour, and of properties as the way to override this default behaviour.
                          >
                          Plus it's
                          really hard to choose crappy accessor name.
                          >
                          What about getMyCrappyAttr ibuteName/setMyCrappyAttr ibuteName ?-)
                          >
                          >
                          >
                          --
                          bruno desthuilliers
                          python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
                          p in 'onurb@xiludom. gro'.split('@')])"

                          Comment

                          • Maric Michaud

                            #14
                            Re: Accessors in Python (getters and setters)

                            Le mercredi 12 juillet 2006 11:17, mystilleef a écrit :
                            Yes, it is possible to name crappy accessors too (e.g set_tmp/get_tmp).
                            But developers tend to pay more attention to given methods/functions
                            less crappy names, at least when compared to data attributes.
                            Not python developers.
                            This
                            stems from the fact that in many languages data attributes aren't
                            usually part of the API, as well as the whole OO(Encapsulatio n) blah
                            blah. I know I would not name the accessors set_tmp/get_tmp, because my
                            philosophy is that methods/functions need to have meaningful names and
                            state their intended purpose.
                            But that's not python philosophy.
                            I don't hold data attributes to such
                            standards and I imagine many developers don't either and least based on
                            other people's code I've read. Plus there are many occassions when
                            attributes are not intended to be APIs, but eventually become one.
                            But they are in Python and that is the python's philosophy. All attribute or
                            method not beginning with an '_' *is* API.
                            After all most data attributes are created with the purpose of serving
                            methods.
                            And in python the reverse can be true :

                            class a(object) :
                            def __init__(self, ro_attr) : self.__attr = ro_attr
                            def _getAttr(self) :
                            """A method which serves an attribute"""
                            return self.__attr
                            attr = property(_getAt tr)




                            --
                            _____________

                            Maric Michaud
                            _____________

                            Aristote - www.aristote.info
                            3 place des tapis
                            69004 Lyon
                            Tel: +33 426 880 097

                            Comment

                            • Bruno Desthuilliers

                              #15
                              Re: Accessors in Python (getters and setters)

                              mystilleef wrote:
                              Lousy Attribute Name:
                              self.tmp
                              >
                              Accessors:
                              set_temporary_b uffer
                              get_temporary_b uffer
                              >
                              The attribute name I chose, "tmp" sucks.
                              Well, it's surely not as descriptive as 'temporary_buff er'
                              I have used that name in
                              dozens of places spanning over 27000 LOC.
                              Too bad for you.
                              There's a chance that other
                              develops might misinterpret exactly what "tmp" does. Plus I don't want
                              emails from other developers querying me about what "tmp" is/does.
                              "tmp" is obvious to me, but not necessarily to others.
                              So why did you name it that way at first ?
                              Now compare that
                              to the accessors.
                              But 'tmp' actually *is* an accessor.
                              Not only do they improve readability
                              Err... do you find:

                              obj.set_tempora ry_buffer(val)
                              val = obj.get_tempora ry_buffer()

                              really more readable than:

                              obj.temporary_b uffer = val
                              val = obj.temporary_b uffer

                              at the expense
                              of more code,
                              Indeed. In both the class and client code.
                              they actually allow me to change the lousily named
                              attribute "tmp" to "temporary_buff er" without grepping, seding,
                              searching, replacing and praying.
                              You still fail to get the point. You actually choose a crappy name for a
                              *public* property. It's *exactly* as if, in Java, you had named your
                              getter/setter 'get_tmp' and 'set_tmp'.
                              Sure, if you are dealing with less
                              than a 1000LOC you can get away with using "tmp" or renaming it easily.
                              But if you are dealing with a much larger code base and more
                              developers, issues like this rapidly become a nuisance.
                              Indeed. But it's *your* responsability to choose good names for the API.
                              Yes, it is possible to name crappy accessors too (e.g set_tmp/get_tmp).
                              or 'tmp'.
                              But developers tend to pay more attention to given methods/functions
                              less crappy names, at least when compared to data attributes.
                              s/developpers/you/
                              This
                              stems from the fact that in many languages data attributes aren't
                              usually part of the API,
                              Once again, in Python, there is *no* such thing as 'data attributes'.
                              *All* attributes are *objects* - some of them callable.
                              as well as the whole OO(Encapsulatio n) blah
                              blah.
                              Don't confuse encapsulation with data-hiding.
                              I know I would not name the accessors set_tmp/get_tmp, because my
                              philosophy is that methods/functions need to have meaningful names and
                              state their intended purpose.
                              That's true for each and every name in a program.
                              I don't hold data attributes to such
                              standards
                              Too bad for you.
                              and I imagine many developers don't either and least based on
                              other people's code I've read. Plus there are many occassions when
                              attributes are not intended to be APIs,
                              Then mark them as being implementation (ie : prefix them with a single
                              underscore).
                              but eventually become one.
                              After all most data attributes are created with the purpose of serving
                              methods.
                              Nope. You have the class API, and the class implementation. Both made of
                              both callable and non-callable attributes.

                              Mystilleef, I do share your pain (really - been here, done that,
                              etc...), and I understand that grasping Python requires some mental
                              adjustments when coming from Java and friends (been here, done that,
                              etc...). But you seriously can't blame the language for your own mistakes.

                              If you intented 'tmp' to be part of the API, then you're responsible for
                              the bad naming. If you didn't, then you're responsible for breaking the
                              encapsulation - FWIW, following the convention (single leading
                              underscore) could have make it clearer to you. In both cases, you
                              happily used a bad name in 27 KLOC - so you really had a lot of time and
                              occasions to notice something wrong with this.

                              --
                              bruno desthuilliers
                              python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
                              p in 'onurb@xiludom. gro'.split('@')])"

                              Comment

                              Working...