property() usage - is this as good as it gets?

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

    property() usage - is this as good as it gets?

    Hi,

    I want to manage and control access to several important attributes in
    a class and override the behaviour of some of them in various
    subclasses.

    Below is a stripped version of how I've implemented this in my current
    bit of work.

    It works well enough, but I can't help feeling there a cleaner more
    readable way of doing this (with less duplication, etc).

    Is this as good as it gets or can this be refined and improved
    especially if I was to add in a couple more attributes some fairly
    complex over-ride logic?

    #!/usr/bin/env python

    class A(object):
    def __init__(self):
    self._x = None
    self._y = None

    def _set_x(self, value):
    self._x = value

    def _get_x(self):
    return self._x

    x = property(_get_x , _set_x)

    def _set_y(self, value):
    self._y = value

    def _get_y(self):
    return self._y

    y = property(_get_y , _set_y)

    class B(A):
    def __init__(self):
    self._z = None
    super(B, self).__init__( )

    def _set_x(self, x):
    # An example subclass 'set' override.
    if x == 10:
    raise Exception('%r is invalid!' % x)
    self._x = x

    x = property(A._get _x, _set_x)

    def _set_z(self, value):
    self._z = value

    def _get_z(self):
    return self._z

    z = property(_get_z , _set_z)

    del A._get_x, A._set_x, A._get_y, A._set_y
    del B._set_x, B._get_z, B._set_z
  • castironpi

    #2
    Re: property() usage - is this as good as it gets?

    On Aug 22, 11:18 am, David Moss <drk...@gmail.c omwrote:
    Hi,
    >
    I want to manage and control access to several important attributes in
    a class and override the behaviour of some of them in various
    subclasses.
    >
    Below is a stripped version of how I've implemented this in my current
    bit of work.
    >
    It works well enough, but I can't help feeling there a cleaner more
    readable way of doing this (with less duplication, etc).
    >
    Is this as good as it gets or can this be refined and improved
    especially if I was to add in a couple more attributes some fairly
    complex over-ride logic?
    >
    #!/usr/bin/env python
    >
    class A(object):
        def __init__(self):
            self._x = None
            self._y = None
    >
        def _set_x(self, value):
            self._x = value
    >
        def _get_x(self):
            return self._x
    >
        x = property(_get_x , _set_x)
    >
        def _set_y(self, value):
            self._y = value
    >
        def _get_y(self):
            return self._y
    >
        y = property(_get_y , _set_y)
    Within the bounds of Python, that's it.

    In the cases where you're not executing code on 'get' or 'set', it
    might be possible to have a default getter/setter, that just sets the
    value of a variable name. This keeps your interface the same across
    inheritance and changes. Possible to have it assign a default value
    too.

    def _set_z(self, value):
    self._z = value

    #def _get_z(self):
    # return self._z

    z = property( True, _set_z ) #still gets self._z

    Unless, you are looking at something 'periodic' or regular. From
    something I'm working on:

    def _getbalance( self ):
    return self._tree.geti (
    self.where+ self.lookup[ 'balance' ] )

    def _getparent( self ):
    return self._tree.getI (
    self.where+ self.lookup[ 'parent' ] )

    Where 'balance' and 'parent' could both come from something generic:

    balance= property( tree_lookup( 'balance' ) )
    parent= property( tree_lookup( 'parent' ) )

    They would have to take care to define 'self' properly and everything.

    Comment

    • Miles

      #3
      Re: property() usage - is this as good as it gets?

      On Fri, Aug 22, 2008 at 12:18 PM, David Moss <drkjam@gmail.c omwrote:
      Hi,
      >
      I want to manage and control access to several important attributes in
      a class and override the behaviour of some of them in various
      subclasses.
      >
      Below is a stripped version of how I've implemented this in my current
      bit of work.
      >
      It works well enough, but I can't help feeling there a cleaner more
      readable way of doing this (with less duplication, etc).
      It could certainly be made more concise, without changing the meaning:

      ###

      from operator import attrgetter
      class attrsetter(obje ct):
      def __init__(self, attr):
      self._attr = attr
      def __call__(self, object, value):
      setattr(object, self._attr, value)
      def defaultproperty (attr):
      return property(attrge tter(attr), attrsetter(attr ))

      class A(object):
      def __init__(self):
      self._x = None
      self._y = None

      x = defaultproperty ('_x')
      y = defaultproperty ('_y')

      class B(A):
      def __init__(self):
      super(B, self).__init__( )
      self._z = None

      def _set_x(self, x):
      # An example subclass 'set' override.
      if x == 10:
      raise Exception('%r is invalid!' % x)
      self._x = x

      x = property(A.x.fg et, _set_x)
      z = defaultproperty ('_z')
      # You really don't need to do this, but you can if you want
      del _set_x

      ###

      But, given the example you gave, you could also write things this way
      (aside from no longer forbidding deleting the properties, which really
      shouldn't be necessary):

      ###

      class A(object):
      def __init__(self):
      self.x = None
      self.y = None

      class B(A):
      def __init__(self):
      super(B, self).__init__( )
      self._x = self.x
      self.z = None

      def _set_x(self, x):
      # An example subclass 'set' override.
      if x == 10:
      raise Exception('%r is invalid!' % x)
      self._x = x

      x = property(attrge tter('_x'), _set_x)

      ###

      It's difficult to know exactly what would work best for you without a
      better idea of how your properties override each other.

      -Miles

      Comment

      • George Sakkis

        #4
        Re: property() usage - is this as good as it gets?

        On Aug 22, 12:18 pm, David Moss <drk...@gmail.c omwrote:
        Hi,
        >
        I want to manage and control access to several important attributes in
        a class and override the behaviour of some of them in various
        subclasses.
        >
        Below is a stripped version of how I've implemented this in my current
        bit of work.
        >
        It works well enough, but I can't help feeling there a cleaner more
        readable way of doing this (with less duplication, etc).
        >
        Is this as good as it gets or can this be refined and improved
        especially if I was to add in a couple more attributes some fairly
        complex over-ride logic?
        A small improvement as far as overriding goes is the OProperty recipe:
        http://infinitesque.ne t/articles/2005/enhancing%20Pyt hon's%20propert y.xhtml

        George

        Comment

        • Christian Heimes

          #5
          Re: property() usage - is this as good as it gets?

          David Moss wrote:
          Hi,
          >
          I want to manage and control access to several important attributes in
          a class and override the behaviour of some of them in various
          subclasses.
          >
          Below is a stripped version of how I've implemented this in my current
          bit of work.
          >
          It works well enough, but I can't help feeling there a cleaner more
          readable way of doing this (with less duplication, etc).
          >
          Is this as good as it gets or can this be refined and improved
          especially if I was to add in a couple more attributes some fairly
          complex over-ride logic?
          The extended property type in Python 2.6 makes it much easier to
          overwrite the getter, sett or deleter of a property:

          The Python interpreter has a number of functions and types built into it that are always available. They are listed here in alphabetical order.,,,, Built-in Functions,,, A, abs(), aiter(), all(), a...


          class C(object):
          def __init__(self): self._x = None

          @property
          def x(self):
          """I'm the 'x' property."""
          return self._x

          @x.setter
          def x(self, value):
          self._x = value

          @x.deleter
          def x(self):
          del self._x

          class D(C):
          @C.x.getter
          def x(self):
          return 2 * self._x

          @x.setter
          def x(self, value):
          self._x = value // 2

          Christian

          Comment

          • Medardo Rodriguez

            #6
            Re: property() usage - is this as good as it gets?

            On Fri, Aug 22, 2008 at 1:49 PM, Miles <semanticist@gm ail.comwrote:
            from operator import attrgetter
            class attrsetter(obje ct):
            def __init__(self, attr):
            self._attr = attr
            def __call__(self, object, value):
            setattr(object, self._attr, value)
            This solution is very nice, but in programming is a good practice to be uniform:
            The interface of "attrgetter " is "def attrgetter(*nam es): ..."
            So, it will be nice the same for attrsetter: "def attrsetter(*nam es):"

            I will send an example, but extending it a little bit and also using
            some nice python structures of functional programming:

            #<code>
            from operator import attrgetter

            def attrsetter(*nam es):
            def closure(obj, *values):
            for i in xrange(len(name s)):
            setattr(obj, names[i], values[i])
            return closure

            attrmanager = lambda name: (attrgetter(nam e), attrsetter(name ))


            class Test(object):
            x = property(*attrm anager('_x'))
            y = property(*attrm anager('_y'))

            setvalues = attrsetter('x', 'y')


            test = Test()

            test.x = 1
            print 'test.x:', test.x

            test.y = 'Merchise'
            print 'test.y:', test.y


            # Just another test

            test.setvalues( 3, 'med')

            print 'test.x:', test.x
            print 'test.y:', test.y
            #</code>

            Regards

            Comment

            • castironpi

              #7
              Re: property() usage - is this as good as it gets?

              On Aug 22, 11:18 am, David Moss <drk...@gmail.c omwrote:
              Hi,
              >
              I want to manage and control access to several important attributes in
              a class and override the behaviour of some of them in various
              subclasses.
              >
              Below is a stripped version of how I've implemented this in my current
              bit of work.
              >
              It works well enough, but I can't help feeling there a cleaner more
              readable way of doing this (with less duplication, etc).
              >
              Is this as good as it gets or can this be refined and improved
              especially if I was to add in a couple more attributes some fairly
              complex over-ride logic?
              >
              #!/usr/bin/env python
              >
              class A(object):
              def __init__(self):
              self._x = None
              self._y = None
              >
              def _set_x(self, value):
              self._x = value
              >
              def _get_x(self):
              return self._x
              >
              x = property(_get_x , _set_x)
              >
              def _set_y(self, value):
              self._y = value
              >
              def _get_y(self):
              return self._y
              >
              y = property(_get_y , _set_y)
              To the OP: you have a unique procedure executed for every attribute of
              an instance, for each of set, get, and del. That's a lot of code. If
              you don't want unique procedures, what patterns should they follow?
              What is wrong with the way you overrode 'get_x' above? When
              brainstorming, don't restrict yourself to Python syntax-- make
              something up, and we'll write Python.

              Comment

              • alex23

                #8
                Re: property() usage - is this as good as it gets?

                castironpi <castiro...@gma il.comwrote:
                and we'll write Python.
                I haven't seen anything you've contributed to this group that would so
                far be considered well-written Python.

                Confusing and border-line insane, yes. Pythonic? Not at all.

                Here's a tip: try actually developing some real-world application in
                Python for a while, rather than the god-knows-what-you're-doing
                attempts that you keep hijacking various threads with. Your code isn't
                anywhere near as clever as you seem to think.

                Comment

                • Raymond Hettinger

                  #9
                  Re: property() usage - is this as good as it gets?

                  On Aug 22, 1:18 pm, David Moss <drk...@gmail.c omwrote:
                  It works well enough, but I can't help feeling there a cleaner more
                  readable way of doing this (with less duplication, etc).
                  >
                  Is this as good as it gets or can this be refined and improved
                  especially if I was to add in a couple more attributes some fairly
                  complex over-ride logic?
                  >
                  #!/usr/bin/env python
                  >
                  class A(object):
                      def __init__(self):
                          self._x = None
                          self._y = None
                  >
                      def _set_x(self, value):
                          self._x = value
                  >
                      def _get_x(self):
                          return self._x
                  >
                      x = property(_get_x , _set_x)
                  >
                      def _set_y(self, value):
                          self._y = value
                  >
                      def _get_y(self):
                          return self._y
                  >
                      y = property(_get_y , _set_y)

                  FWIW, there is a variant of property() that allows you to re-use the
                  same getter/setter code for multiple attributes:




                  Raymond Hettinger

                  Comment

                  • castironpi

                    #10
                    Re: property() usage - is this as good as it gets?

                    On Aug 24, 5:00 am, alex23 <wuwe...@gmail. comwrote:
                    castironpi <castiro...@gma il.comwrote:
                    and we'll write Python.
                    >
                    I haven't seen anything you've contributed to this group that would so
                    far be considered well-written Python.
                    >
                    Confusing and border-line insane, yes. Pythonic? Not at all.
                    >
                    Here's a tip: try actually developing some real-world application in
                    Python for a while, rather than the god-knows-what-you're-doing
                    attempts that you keep hijacking various threads with. Your code isn't
                    anywhere near as clever as you seem to think.
                    Python isn't as clever as you think. It's a language. Do you want a
                    link to clever code? I like to encourage creativity.

                    Comment

                    • alex23

                      #11
                      Re: property() usage - is this as good as it gets?

                      castironpi <castiro...@gma il.comwrote:
                      Python isn't as clever as you think.  It's a language.  
                      Yet another non-sequitur response from you. At which point in my post
                      did I make any such claims about Python's 'cleverness'?
                      Do you want a
                      link to clever code?  
                      Not if you wrote it or find it clever, no.

                      To quote Kernighan: "Debugging is twice as hard as writing the code in
                      the first place. Therefore, if you write the code as cleverly as
                      possible, you are, by definition, not smart enough to debug it."

                      When the code in question is one of the abstract monstrosities you
                      regularly post here - often in response to _new python users_ asking
                      _basic_ questions that _don't require metaclass solutions_ - I've
                      repeatedly found the cost in interpreting it is just never worth the
                      time and effort required.
                      I like to encourage creativity.
                      Then why do you seem to stymie it? Care to go back through the
                      responses to your posts and tally up the "thanks, that makes sense!"
                      replies to the "I don't get what you mean here" ones?

                      If you're seriously attempting to educate, you're failing. If you're
                      trying to show how blazingly clever you are, you're failing at that,
                      too.

                      When people seem to generally consider you a markov chainer, that -
                      should- be a sign to work on the clarity of your communication.

                      Comment

                      • castironpi

                        #12
                        Re: property() usage - is this as good as it gets?

                        On Aug 24, 7:43 pm, alex23 <wuwe...@gmail. comwrote:
                        castironpi <castiro...@gma il.comwrote:
                        Python isn't as clever as you think.  It's a language.  
                        >
                        Yet another non-sequitur response from you. At which point in my post
                        did I make any such claims about Python's 'cleverness'?
                        >
                        Do you want a
                        link to clever code?  
                        >
                        Not if you wrote it or find it clever, no.
                        >
                        To quote Kernighan: "Debugging is twice as hard as writing the code in
                        the first place. Therefore, if you write the code as cleverly as
                        possible, you are, by definition, not smart enough to debug it."
                        >
                        When the code in question is one of the abstract monstrosities you
                        regularly post here - often in response to _new python users_ asking
                        _basic_ questions that _don't require metaclass solutions_ - I've
                        repeatedly found the cost in interpreting it is just never worth the
                        time and effort required.
                        >
                        I like to encourage creativity.
                        >
                        Then why do you seem to stymie it? Care to go back through the
                        responses to your posts and tally up the "thanks, that makes sense!"
                        replies to the "I don't get what you mean here" ones?
                        >
                        If you're seriously attempting to educate, you're failing. If you're
                        trying to show how blazingly clever you are, you're failing at that,
                        too.
                        >
                        When people seem to generally consider you a markov chainer, that -
                        should- be a sign to work on the clarity of your communication.
                        I'm baffled. I don't understand what you write. I think someone in
                        my shoes would be justified in dismissing it as either malicious or a
                        miscommunicatio n. My typical response is, take something I've said in
                        context, and show how it fulfills the criteria you describe.

                        For instance, "I won't like it if you do" and "I won't think it's
                        clever if you do" aren't consistent belief structures, they're fight
                        structures. You have made such claims.

                        In the post above, I make two claims, ask two questions, and encourage
                        a brainstorm. I don't see how what you say applies to it.

                        I am willing to change the way I communicate. I want to communicate
                        effectively. But, until someone takes something I want to say, and
                        says it the right way, I can't learn how. So I wait and write Python,
                        and share my frustration with my peers.

                        Lastly, in the syllogism you propose, "not smart enough to debug it",
                        you equate maximally clever writing with maximally clever debugging,
                        which is clearly wrong. They are distinct; someone could be better at
                        either one than the other. And besides, your quoted premise "twice as
                        hard" is assumed, not proven.

                        Comment

                        • alex23

                          #13
                          Re: property() usage - is this as good as it gets?

                          On Aug 25, 12:42 pm, castironpi <castiro...@gma il.comwrote:
                          I'm baffled.  I don't understand what you write.  
                          Which is pretty much how I feel about -all- of your posts.
                          I think someone in
                          my shoes would be justified in dismissing it as either malicious or a
                          miscommunicatio n.  
                          No, it's frustration at the sharp decrease in signal:noise that this
                          newsgroup has undertaken since your arrival.
                          My typical response is, take something I've said in
                          context, and show how it fulfills the criteria you describe.
                          Generally, it's -extremely difficult- understanding your context, for
                          starters. But how about this, your code snippet from this very thread,
                          your -first- of two seemingly independent replies to the original
                          post:
                          def _getbalance( self ):
                          return self._tree.geti (
                          self.where+ self.lookup[ 'balance' ] )
                          >
                          def _getparent( self ):
                          return self._tree.getI (
                          self.where+ self.lookup[ 'parent' ] )
                          >
                          Where 'balance' and 'parent' could both come from something generic:
                          >
                          balance= property( tree_lookup( 'balance' ) )
                          parent= property( tree_lookup( 'parent' ) )
                          In your 'example', you reference one marked-as-implementation
                          attribute, two unspecified attributes, one unspecified method and one
                          unspecified function. That you refer to one function as both 'geti'
                          and 'getI' leads me to believe this -isn't- workable code and you've
                          just re-keyed this in without testing.

                          I've also -no- idea what you're trying to demonstrate here. It's not
                          clear nor obvious, and I can't see how your _getwhatever methods tie
                          in with the property definition.
                          For instance, "I won't like it if you do" and "I won't think it's
                          clever if you do" aren't consistent belief structures, they're fight
                          structures.  You have made such claims.
                          No, what I've stated is I've yet to see -any- code samples that you've
                          provided be of any real, clear use to -anyone-. This isn't a 'fight
                          structure', this is an opinion formed by the overwhelming amount of
                          evidence you keep contributing to this group.
                          In the post above, I make two claims, ask two questions, and encourage
                          a brainstorm.  I don't see how what you say applies to it.
                          What you said was: "When brainstorming, don't restrict yourself to
                          Python syntax-- make
                          something up, and we'll write Python."

                          What I'm contesting is your ability to write Python.

                          Furthermore, people -aren't- posting questions to the "castironpi
                          hour", they're asking questions to help further their understanding of
                          Python, not to give you further opportunity to emphasise your
                          misunderstandin g of it. Suggesting they 'brainstorm' without any
                          understanding of the language itself and that you'll somehow magically
                          generate Python code for them is, based on what you've written here,
                          laughable.
                          I am willing to change the way I communicate.  I want to communicate
                          effectively.  But, until someone takes something I want to say, and
                          says it the right way, I can't learn how.  So I wait and write Python,
                          and share my frustration with my peers.
                          Given how many people have publicly killfiled you on this group, I'm
                          not sure who you consider to be your 'peers'. There was a -lot- of
                          initial frustration at your post, along with even more dismissal of it
                          as the output of a poorly written AI experiment.

                          You're -failing- the Turing test. If that isn't telling you something
                          is wrong with your communication style, I don't really know what will.
                          Lastly, in the syllogism you propose, "not smart enough to debug it",
                          you equate maximally clever writing with maximally clever debugging,
                          which is clearly wrong.  They are distinct; someone could be better at
                          either one than the other.  And besides, your quoted premise "twice as
                          hard" is assumed, not proven.
                          Assumed by someone whose programming knowledge I have a -lot- more
                          respect for than your's, mostly because Kernighan's is -more than
                          amply demonstrated-.

                          Which leads me to reiterate my original statement, only framing it now
                          as a question: what -real world- applications or systems have you
                          worked on...in -any- language? I find it difficult to believe you've
                          ever worked on any, or even more pointedly, had to work on -someone
                          else's real world code-. Because the sample code fragments you post,
                          when not broken, at best seem to relate to pointless wankery on your
                          behalf, without any practical application whatsoever, and at worst
                          carry deep-seated misunderstandin gs about how Python works.

                          Comment

                          • Gabriel Genellina

                            #14
                            Re: property() usage - is this as good as it gets?

                            En Mon, 25 Aug 2008 00:41:42 -0300, alex23 <wuwei23@gmail. comescribió:
                            On Aug 25, 12:42 pm, castironpi <castiro...@gma il.comwrote:
                            >I'm baffled.  I don't understand what you write.  
                            Which is pretty much how I feel about -all- of your posts.
                            May I ask both of you to continue this in private?

                            --
                            Gabriel Genellina

                            Comment

                            • alex23

                              #15
                              Re: property() usage - is this as good as it gets?

                              On Aug 25, 3:03 pm, "Gabriel Genellina" <gagsl-...@yahoo.com.a r>
                              wrote:
                              May I ask both of you to continue this in private?
                              Certainly. But be warned, I -will- continue posting publicly if I
                              believe someone is misinforming others here, whether it's willful or
                              not.

                              Comment

                              Working...