overriding a property

Discussion in 'Python' started by Lucasm, Oct 19, 2010.

  1. Lucasm

    Lucasm Guest

    Hi,

    A question. Is it possible to dynamically override a property?

    class A(object):
    @property
    def return_five(self):
    return 5

    I would like to override the property for an instance of A to say the
    string 'bla'.
    Lucasm, Oct 19, 2010
    #1
    1. Advertising

  2. Lucasm <lordlucraft <at> gmail.com> writes:


    > I would like to override the property for an instance of A to say the
    > string 'bla'.


    A.return_five = "blah"
    Benjamin Peterson, Oct 19, 2010
    #2
    1. Advertising

  3. Lucasm

    John Posner Guest

    On 10/19/2010 9:39 AM, Lucasm wrote:
    > Hi,
    >
    > A question. Is it possible to dynamically override a property?
    >
    > class A(object):
    > @property
    > def return_five(self):
    > return 5
    >
    > I would like to override the property for an instance of A to say the
    > string 'bla'.


    Is this the sort of thing you're looking for ...

    #-------------------------------------
    import inspect

    class A(object):
    @property
    def return_five(self):
    try:
    # get name of this function ...
    frm = inspect.getframeinfo(inspect.currentframe())
    # ... and use it as dict key
    return self.__dict__[frm.function]

    except KeyError:
    # attr not set in instance
    return 5

    a = A()
    print "one:", a.return_five

    b = A()
    b.__dict__['return_five'] = 'bla'
    print "two:", b.return_five

    c = A()
    print "three:", c.return_five
    #-------------------------------------

    The output is:

    one: 5
    two: bla
    three: 5

    If you don't want to fool around with the inspect module, you can
    hard-code the function name as the instance's dict key:

    return self.__dict__['return_five']

    HTH,
    John
    John Posner, Oct 19, 2010
    #3
  4. On Tue, 19 Oct 2010 06:39:56 -0700, Lucasm wrote:

    > Hi,
    >
    > A question. Is it possible to dynamically override a property?
    >
    > class A(object):
    > @property
    > def return_five(self):
    > return 5
    >
    > I would like to override the property for an instance of A to say the
    > string 'bla'.



    >>> class A(object):

    .... _five = 5 # class attribute shared by all instances
    .... @property
    .... def return_five(self):
    .... return self._five
    ....
    >>>
    >>> a = A()
    >>> a._five = 'bla' # set an instance attribute
    >>> b = A()
    >>> print a.return_five

    bla
    >>> print b.return_five

    5



    --
    Steven
    Steven D'Aprano, Oct 19, 2010
    #4
  5. Lucasm

    Lucasm Guest

    On 19 Okt, 16:07, Benjamin Peterson <> wrote:
    > Lucasm <lordlucraft <at> gmail.com> writes:
    >
    > > I would like to override the property for an instance of A to say the
    > > string 'bla'.

    >
    > A.return_five = "blah"


    I guess you did not test that. :)
    Lucasm, Oct 20, 2010
    #5
  6. Lucasm

    Lucasm Guest

    On 19 Okt, 18:28, Steven D'Aprano <st...@REMOVE-THIS-
    cybersource.com.au> wrote:
    > On Tue, 19 Oct 2010 06:39:56 -0700, Lucasm wrote:
    > > Hi,

    >
    > > A question. Is it possible to dynamically override a property?

    >
    > > class A(object):
    > >     @property
    > >     def return_five(self):
    > >         return 5

    >
    > > I would like to override the property for an instance of A to say the
    > > string 'bla'.
    > >>> class A(object):

    >
    > ...     _five = 5  # class attribute shared by all instances
    > ...     @property
    > ...     def return_five(self):
    > ...         return self._five
    > ...
    >
    > >>> a = A()
    > >>> a._five = 'bla'  # set an instance attribute
    > >>> b = A()
    > >>> print a.return_five

    > bla
    > >>> print b.return_five

    >
    > 5
    >
    > --
    > Steven


    Thanks for the answers. I would like to override the property though
    without making special modifications in the main class beforehand. Is
    this possible?
    Lucasm, Oct 20, 2010
    #6
  7. Lucasm

    Peter Otten Guest

    Lucasm wrote:

    > On 19 Okt, 18:28, Steven D'Aprano <st...@REMOVE-THIS-
    > cybersource.com.au> wrote:
    >> On Tue, 19 Oct 2010 06:39:56 -0700, Lucasm wrote:
    >> > Hi,

    >>
    >> > A question. Is it possible to dynamically override a property?

    >>
    >> > class A(object):
    >> > @property
    >> > def return_five(self):
    >> > return 5

    >>
    >> > I would like to override the property for an instance of A to say the
    >> > string 'bla'.
    >> >>> class A(object):

    >>
    >> ... _five = 5 # class attribute shared by all instances
    >> ... @property
    >> ... def return_five(self):
    >> ... return self._five
    >> ...
    >>
    >> >>> a = A()
    >> >>> a._five = 'bla' # set an instance attribute
    >> >>> b = A()
    >> >>> print a.return_five

    >> bla
    >> >>> print b.return_five

    >>
    >> 5
    >>
    >> --
    >> Steven

    >
    > Thanks for the answers. I would like to override the property though
    > without making special modifications in the main class beforehand. Is
    > this possible?


    You can dynamically change the instance's class:

    >>> class A(object):

    .... @property
    .... def five(self): return 5
    ....
    >>> a = A()
    >>> b = A()
    >>> class B(type(b)):

    .... @property
    .... def five(self): return "FIVE"
    ....
    >>> b.__class__ = B
    >>> a.five

    5
    >>> b.five

    'FIVE'

    But still -- what you are trying looks like a bad idea. What's your usecase?

    Peter
    Peter Otten, Oct 20, 2010
    #7
  8. Lucasm

    Lucasm Guest

    On 20 Okt, 16:09, Peter Otten <> wrote:
    > Lucasm wrote:
    > > On 19 Okt, 18:28, Steven D'Aprano <st...@REMOVE-THIS-
    > > cybersource.com.au> wrote:
    > >> On Tue, 19 Oct 2010 06:39:56 -0700, Lucasm wrote:
    > >> > Hi,

    >
    > >> > A question. Is it possible to dynamically override a property?

    >
    > >> > class A(object):
    > >> > @property
    > >> > def return_five(self):
    > >> > return 5

    >
    > >> > I would like to override the property for an instance of A to say the
    > >> > string 'bla'.
    > >> >>> class A(object):

    >
    > >> ...     _five = 5  # class attribute shared by all instances
    > >> ...     @property
    > >> ...     def return_five(self):
    > >> ...         return self._five
    > >> ...

    >
    > >> >>> a = A()
    > >> >>> a._five = 'bla'  # set an instance attribute
    > >> >>> b = A()
    > >> >>> print a.return_five
    > >> bla
    > >> >>> print b.return_five

    >
    > >> 5

    >
    > >> --
    > >> Steven

    >
    > > Thanks for the answers. I would like to override the property though
    > > without making special modifications in the main class beforehand. Is
    > > this possible?

    >
    > You can dynamically change the instance's class:
    >
    > >>> class A(object):

    >
    > ...     @property
    > ...     def five(self): return 5
    > ...>>> a = A()
    > >>> b = A()
    > >>> class B(type(b)):

    >
    > ...     @property
    > ...     def five(self): return "FIVE"
    > ...>>> b.__class__ = B
    > >>> a.five

    > 5
    > >>> b.five

    >
    > 'FIVE'
    >
    > But still -- what you are trying looks like a bad idea. What's your usecase?
    >
    > Peter


    Thanks for your answer. That's exactly the thing I'm doing right now
    and it works :) My use case is testing. I want to test a class and
    reduce the complexity of the output generated by certain properties.
    It would be nice to know alternatives to this approach.
    Lucasm, Oct 20, 2010
    #8
  9. Lucasm

    John Posner Guest

    On 10/20/2010 9:59 AM, Lucasm wrote:

    <snip>

    > Thanks for the answers. I would like to override the property though
    > without making special modifications in the main class beforehand. Is
    > this possible?


    Take a look at http://docs.python.org/reference/datamodel.html#descriptors

    The last paragraph of Section 3.4.2.3. Invoking Descriptors says:

    The property() function is implemented as a data descriptor.
    Accordingly, instances cannot override the behavior of a property.

    -John
    John Posner, Oct 20, 2010
    #9
  10. Lucasm <> writes:

    > Thanks for the answers. I would like to override the property though
    > without making special modifications in the main class beforehand. Is
    > this possible?


    That will not be easy. When you access obj.return_five, python looks up
    'return_five' in type(obj) to see what the return_five property even
    means. (See http://users.rcn.com/python/download/Descriptor.htm for
    details of how this works.)

    Since you can't change the source of A, you are left with two options:
    you can monkey-patch A.return_five to make it optionally consult the
    instance, or you can assign to instance's __class__ to make it point to
    a subclass of A that implements a different 'return_five'. Both options
    are fairly unpleasant, but I think I'd go with the first one.

    Others have spelled out the __class__-changing variant. While
    monkey-patching is not the cleanest of practices to adopt, in my mind it
    still beats assigning to __class__. Here is an example:

    # Wrap return_five so it supports per-instance customization, but
    # without copy-pasting the original.
    def wrap_return_five(orig):
    @property
    def wrapper(self):
    if 'return_five' in self.__dict__:
    return self.__dict__['return_five']
    return orig.__get__(self, type(self))
    return wrapper

    >>> A.return_five = wrap_return_five(A.return_five)
    >>> a = A()
    >>> b = A()
    >>> a.return_five

    5
    >>> a.__dict__['return_five'] = 10
    >>> a.return_five

    10
    >>> b.return_five

    5

    If you want, you can make a.return_five itself settable, but I'll leave
    that as an excercise for the reader.
    Hrvoje Niksic, Oct 20, 2010
    #10
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Eric Newton
    Replies:
    3
    Views:
    9,377
    Brock Allen
    Apr 4, 2005
  2. Joshua Beall
    Replies:
    1
    Views:
    419
    Bertilo Wennergren
    Dec 10, 2003
  3. Dietmar Gräbner
    Replies:
    1
    Views:
    384
    Priscilla Walmsley
    Jul 19, 2004
  4. Olaf Klischat
    Replies:
    4
    Views:
    546
    Olaf Klischat
    Nov 23, 2009
  5. Jimmy Seow

    Problem Overriding Enabled Property in Composite Control

    Jimmy Seow, Apr 11, 2004, in forum: ASP .Net Web Controls
    Replies:
    0
    Views:
    275
    Jimmy Seow
    Apr 11, 2004
Loading...

Share This Page