Really virtual properties

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

    #1

    Really virtual properties

    Hallöchen!

    When I use properties in new style classes, I usually pass get/set
    methods to property(), like this:

    x = property(get_x)

    If I overwrite get_x in a derived class, any access to x still calls
    the base get_x() method. Is there a way to get the child's get_x()
    method called instead?

    (I found the possibility of using an intermediate method _get_x
    which calls get_x but that's ugly.)

    Tschö,
    Torsten.

    --
    Torsten Bronger, aquisgrana, europa vetus
  • Diez B. Roggisch

    #2
    Re: Really virtual properties

    I don't think so - the reason is that property(<gette r>) is evaluated
    in the baseclass, and stores a callable, not a name. the only thing you
    could do is either

    - create a level of indirection, using lambda, to force the lookup:

    x = property(lamda self: self.get_x())

    - use a metaclass, that tries to scan the baseclass for properties
    that uise functionnames which are redefined in the current class, and
    recrerate a new property for those.

    Diez

    Comment

    • Diez B. Roggisch

      #3
      Re: Really virtual properties

      I don't think so - the reason is that property(<gette r>) is evaluated
      in the baseclass, and stores a callable, not a name. the only thing you
      could do is either

      - create a level of indirection, using lambda, to force the lookup:

      x = property(lamda self: self.get_x())

      - use a metaclass, that tries to scan the baseclass for properties
      that uise functionnames which are redefined in the current class, and
      recrerate a new property for those.

      Diez

      Comment

      • Ben Finney

        #4
        Re: Really virtual properties

        Torsten Bronger <bronger@physik .rwth-aachen.de> wrote:[color=blue]
        > Hallöchen!
        >
        > When I use properties in new style classes, I usually pass get/set
        > methods to property(), like this:
        >
        > x = property(get_x)[/color]

        Better is to make it clear that 'get_x' is not intended to be called
        directly. You can do this through the convention of naming the
        function '_get_x', or use this recipe for a namespace-clean approach:

        Sean Ross:
        "This recipe suggests an idiom for property creation that avoids
        cluttering the class space with get/set/del methods that will not
        be used directly."
        <URL:http://aspn.activestat e.com/ASPN/Cookbook/Python/Recipe/205183>
        [color=blue]
        > If I overwrite get_x in a derived class, any access to x still calls
        > the base get_x() method. Is there a way to get the child's get_x()
        > method called instead?[/color]

        Not using the built-in property type. Here is a recipe for a
        LateBindingProp erty that does what you ask:

        Steven Bethard:
        "This recipe provides a LateBindingProp erty callable which allows
        the getter and setter methods associated with the property to be
        overridden in subclasses."
        <URL:http://aspn.activestat e.com/ASPN/Cookbook/Python/Recipe/408713>

        --
        \ "Any sufficiently advanced bug is indistinguishab le from a |
        `\ feature." -- Rich Kulawiec |
        _o__) |
        Ben Finney

        Comment

        • Bengt Richter

          #5
          Re: Really virtual properties

          On Thu, 18 Aug 2005 23:36:58 +0200, Torsten Bronger <bronger@physik .rwth-aachen.de> wrote:
          [color=blue]
          >Hallöchen!
          >
          >When I use properties in new style classes, I usually pass get/set
          >methods to property(), like this:
          >
          > x = property(get_x)
          >
          >If I overwrite get_x in a derived class, any access to x still calls
          >the base get_x() method. Is there a way to get the child's get_x()
          >method called instead?
          >
          >(I found the possibility of using an intermediate method _get_x
          >which calls get_x but that's ugly.)
          >[/color]
          I think this idea of overriding a property access function is ugly in any case,
          but you could do something like this custom descriptor (not tested beyond
          what you see here):
          [color=blue][color=green][color=darkred]
          >>> class RVP(object):[/color][/color][/color]
          ... def __init__(self, gettername):
          ... self.gettername = gettername
          ... def __get__(self, inst, cls=None):
          ... if inst is None: return self
          ... return getattr(inst, self.gettername )()
          ...[color=blue][color=green][color=darkred]
          >>> class Base(object):[/color][/color][/color]
          ... def get_x(self): return 'Base get_x'
          ... x = RVP('get_x')
          ...[color=blue][color=green][color=darkred]
          >>> class Derv(Base):[/color][/color][/color]
          ... def get_x(self): return 'Derv get_x'
          ...[color=blue][color=green][color=darkred]
          >>> b = Base()
          >>> d = Derv()
          >>> b.x[/color][/color][/color]
          'Base get_x'[color=blue][color=green][color=darkred]
          >>> d.x[/color][/color][/color]
          'Derv get_x'

          But why not override the property x in the derived subclass instead,
          with another property x instead of the above very questionable trick? I.e.,
          [color=blue][color=green][color=darkred]
          >>> class Base(object):[/color][/color][/color]
          ... x = property(lambda self: 'Base get_x')
          ...[color=blue][color=green][color=darkred]
          >>> class Derv(Base):[/color][/color][/color]
          ... x = property(lambda self: 'Derv get_x')
          ...[color=blue][color=green][color=darkred]
          >>> b = Base()
          >>> d = Derv()
          >>> b.x[/color][/color][/color]
          'Base get_x'[color=blue][color=green][color=darkred]
          >>> d.x[/color][/color][/color]
          'Derv get_x'

          Regards,
          Bengt Richter

          Comment

          • Steven Bethard

            #6
            Re: Really virtual properties

            Ben Finney wrote:[color=blue]
            > Not using the built-in property type. Here is a recipe for a
            > LateBindingProp erty that does what you ask:
            >
            > Steven Bethard:
            > "This recipe provides a LateBindingProp erty callable which allows
            > the getter and setter methods associated with the property to be
            > overridden in subclasses."
            > <URL:http://aspn.activestat e.com/ASPN/Cookbook/Python/Recipe/408713>[/color]

            Also see Tim Delaney's comment at the bottom, which provides similar
            functionality by subclassing property.

            STeVe

            Comment

            Working...