Properties on old-style classes actually work?

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

    Properties on old-style classes actually work?

    Hello,

    The python library docs read in section 2.1
    (http://docs.python.org/lib/built-in-funcs.html):

    "
    ....

    property( [fget[, fset[, fdel[, doc]]]])
    Return a property attribute for new-style classes (classes that
    derive from object).

    ....
    "


    But in 2.4 at least properties also seem to work for old-style classes:

    class O:

    def __init__(self):
    self._x = 15

    def get_x(self):
    return self._x

    x = property(get_x)

    o = O()
    print o.x

    outputs "15" as expected for the property.

    Regards,
    Paul
  • Steven D'Aprano

    #2
    Re: Properties on old-style classes actually work?

    On Mon, 07 May 2007 10:44:35 +0200, Paul Melis wrote:
    Hello,
    >
    The python library docs read in section 2.1
    (http://docs.python.org/lib/built-in-funcs.html):
    >
    "
    ...
    >
    property( [fget[, fset[, fdel[, doc]]]])
    Return a property attribute for new-style classes (classes that
    derive from object).
    >
    ...
    "
    >
    >
    But in 2.4 at least properties also seem to work for old-style classes:

    Unfortunately, they don't -- they seem to work until you try assigning to
    them. Here's the same property implemented with a new-style and old-style
    class:


    class New(object):
    def __init__(self, s):
    self._value = s
    def upgetter(self):
    return self._value.upp er()
    def upsetter(self, s):
    self._value = s
    value = property(upgett er, upsetter)

    class Old:
    def __init__(self, s):
    self._value = s
    def upgetter(self):
    return self._value.upp er()
    def upsetter(self, s):
    self._value = s
    value = property(upgett er, upsetter)


    Properties work with new-style classes:
    >>obj = New('norwegian blue')
    >>obj.value
    'NORWEGIAN BLUE'
    >>obj.value = 'nobody expects the spanish inquisition!'
    >>obj.value
    'NOBODY EXPECTS THE SPANISH INQUISITION!'


    At first, they seem to work with old-style classes:
    >>obj = Old('norwegian blue')
    >>obj.value
    'NORWEGIAN BLUE'

    But problems occur once you try assigning to it:
    >>obj.value = 'nobody expects the spanish inquisition!'
    >>obj.value
    'nobody expects the spanish inquisition!'

    And now it is easy to see why:
    >>obj.__dict_ _['value']
    'nobody expects the spanish inquisition!'
    >>obj.__dict_ _['_value']
    'norwegian blue'

    The call to assign obj.value over-rides the property with the raw value,
    and from that moment on, obj.value is no longer a property, but just an
    ordinary instance attribute.


    --
    Steven.

    Comment

    • Nick Vatamaniuc

      #3
      Re: Properties on old-style classes actually work?

      On May 7, 4:44 am, Paul Melis <p...@science.u va.nlwrote:
      Hello,
      >
      The python library docs read in section 2.1
      (http://docs.python.org/lib/built-in-funcs.html):
      >
      "
      ...
      >
      property( [fget[, fset[, fdel[, doc]]]])
      Return a property attribute for new-style classes (classes that
      derive from object).
      >
      ...
      "
      >
      But in 2.4 at least properties also seem to work for old-style classes:
      >
      class O:
      >
      def __init__(self):
      self._x = 15
      >
      def get_x(self):
      return self._x
      >
      x = property(get_x)
      >
      o = O()
      print o.x
      >
      outputs "15" as expected for the property.
      >
      Regards,
      Paul
      Paul,

      Sorry to dissapoint, but properties don't work in old style classes.
      The 'get' property seems to work but as soon as you use the set
      property it fails and even 'get' won't work after that. It surely is
      deceiving, I wish it would just give an error or something. See
      below.

      -Nick Vatamaniuc



      >>class O:
      ....: def __init__(self):
      ....: self._x=15
      ....: def get_x(self):
      ....: print "in O.get_x()"
      ....: return self._x
      ....: def set_x(self,newx ):
      ....: print "in O.set_x(newx)"
      ....: self._x=newx
      ....: x=property(get_ x, set_x)
      ....:
      >>o=O()
      >>o._x
      15
      >>o.x
      in O.get_x()
      in O.get_x()
      15
      >>o.x=42
      >>#DANGER WILL ROBINSON, set_x NOT CALLED!!!
      >>o.x
      42
      >>#HMM... properties ARE BROKEN FROM NOW ON
      >>o._x
      15
      >>#...BROKEN INDEED
      >>>

      Comment

      Working...