Re: get descriptor from instance

Discussion in 'Python' started by Gabriel Genellina, Feb 18, 2009.

  1. En Wed, 18 Feb 2009 20:48:17 -0200, Alan G Isaac <>
    escribió:

    > What is a reliable way to get the
    > the property object for an instance attribute?
    > (Or more generally, to get the descriptor
    > controlling an attribute?)
    >
    > If class ``A`` defines the property ``x`` and ``a``
    > in an instance of ``A``, then you can just use
    > ``type(a).__dict__['x']`` to get the property object.
    > But this will not work if the property is inherited.


    type(a).x

    py> class A(object):
    .... def getx(self): return 1
    .... x = property(getx)
    ....
    py> class B(A):
    .... pass
    ....
    py> b=B()
    py> b.x
    1
    py> B.x
    <property object at 0x00B8A690>
    py> type(b).x
    <property object at 0x00B8A690>
    py> getattr(type(b),'x')
    <property object at 0x00B8A690>
    py>

    --
    Gabriel Genellina
     
    Gabriel Genellina, Feb 18, 2009
    #1
    1. Advertising

  2. Gabriel Genellina

    Alan G Isaac Guest

    Re: block dynamic attribute creation (was: get descriptor from instance)

    On 2/18/2009 6:15 PM Gabriel Genellina apparently wrote:
    > type(a).x


    OK, that's good. I'd like to sometimes lock attribute creation on
    instances of a class but still allow properties to function
    correctly. Will something like below be satisfactory?

    Thanks,
    Alan

    def __setattr__(self, attr, val):
    """If instance locked, allow no new attributes."""
    try:
    #get the class attribute if it exists
    p = getattr(type(self),attr)
    #if it's a descriptor, use it to set val
    p.__set__(self, val)
    except AttributeError: #no descriptor
    if hasattr(self, attr): #update val
    self.__dict__[attr] = val
    elif getattr(self, '_attrlock', False):
    raise AttributeError(
    "Set _attrlock to False to add attributes.")
    else:
    #new attributes allowed
    self.__dict__[attr] = val
     
    Alan G Isaac, Feb 19, 2009
    #2
    1. Advertising

  3. Re: block dynamic attribute creation

    Alan G Isaac a écrit :
    > On 2/18/2009 6:15 PM Gabriel Genellina apparently wrote:
    >> type(a).x

    >
    > OK, that's good. I'd like to sometimes lock attribute creation on
    > instances of a class but still allow properties to function
    > correctly. Will something like below be satisfactory?
    >
    >
    > def __setattr__(self, attr, val):
    > """If instance locked, allow no new attributes."""
    > try:
    > #get the class attribute if it exists
    > p = getattr(type(self),attr)
    > #if it's a descriptor, use it to set val
    > p.__set__(self, val)
    > except AttributeError: #no descriptor
    > if hasattr(self, attr): #update val
    > self.__dict__[attr] = val
    > elif getattr(self, '_attrlock', False):
    > raise AttributeError(
    > "Set _attrlock to False to add attributes.")
    > else:
    > #new attributes allowed
    > self.__dict__[attr] = val



    Might be safer to call on the parent class __setattr__ instead of
    directly assigning to the instance's dict Also, your tests in the except
    clause could be simplified:

    if not hasattr(self, attr) and getattr(self, '_attrlock', False):
    raise AttributeError(yadda yadda)
    # NB: assume newstyle class
    super(YourClass, self).__setattr__(attr, val)


    My 2 cents.
     
    Bruno Desthuilliers, Feb 19, 2009
    #3
  4. Re: block dynamic attribute creation (was: get descriptor frominstance)

    En Thu, 19 Feb 2009 01:29:17 -0200, Alan G Isaac <>
    escribió:

    > OK, that's good. I'd like to sometimes lock attribute creation on
    > instances of a class but still allow properties to function
    > correctly. Will something like below be satisfactory?
    >
    > def __setattr__(self, attr, val):
    > """If instance locked, allow no new attributes."""
    > try:
    > #get the class attribute if it exists
    > p = getattr(type(self),attr)
    > #if it's a descriptor, use it to set val
    > p.__set__(self, val)
    > except AttributeError: #no descriptor
    > if hasattr(self, attr): #update val
    > self.__dict__[attr] = val
    > elif getattr(self, '_attrlock', False):
    > raise AttributeError(
    > "Set _attrlock to False to add attributes.")
    > else:
    > #new attributes allowed
    > self.__dict__[attr] = val


    The problem with using __setattr__ is that is slows down *all* attribute
    writes considerably.

    In particular, your code prevents using class attributes as a default
    value for instance attributes (not a big deal, but I like it sometimes),
    and you must remember to set a value for all attributes (even the "hidden"
    ones used by any property). But if you feel OK with that, "just do it". I
    think there are a few recipes in the Python Cookbook about this topic too.

    --
    Gabriel Genellina
     
    Gabriel Genellina, Feb 19, 2009
    #4
  5. Gabriel Genellina

    Alan G Isaac Guest

    Re: block dynamic attribute creation

    >> if hasattr(self, attr): #update val
    >> self.__dict__[attr] = val



    On 2/19/2009 3:54 AM Gabriel Genellina apparently wrote:
    > In particular, your code prevents using class attributes as a default
    > value for instance attributes


    Doesn't the above allow that?

    Thanks,
    Alan
     
    Alan G Isaac, Feb 19, 2009
    #5
  6. Re: block dynamic attribute creation

    En Thu, 19 Feb 2009 13:20:25 -0200, Alan G Isaac <>
    escribió:

    >>> if hasattr(self, attr): #update val
    >>> self.__dict__[attr] = val


    > On 2/19/2009 3:54 AM Gabriel Genellina apparently wrote:
    >> In particular, your code prevents using class attributes as a default
    >> value for instance attributes

    >
    > Doesn't the above allow that?


    Sorry, yes, sure!


    --
    Gabriel Genellina
     
    Gabriel Genellina, Feb 19, 2009
    #6
  7. Gabriel Genellina

    Alan G Isaac Guest

    Re: block dynamic attribute creation

    On 2/19/2009 3:47 AM Bruno Desthuilliers apparently wrote:
    > if not hasattr(self, attr) and getattr(self, '_attrlock', False):
    > raise AttributeError(yadda yadda)
    > # NB: assume newstyle class
    > super(YourClass, self).__setattr__(attr, val)



    Thanks.
    Alan
    PS Thanks also to all who restrained
    themselves from saying, "don't do this".
    ;-)
     
    Alan G Isaac, Feb 19, 2009
    #7
    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. Mike
    Replies:
    2
    Views:
    599
    Matthias Kaeppler
    Feb 27, 2005
  2. Thorsten Knopel
    Replies:
    2
    Views:
    698
    Pete Becker
    Apr 14, 2005
  3. Bill David
    Replies:
    8
    Views:
    807
    CBFalconer
    Sep 10, 2008
  4. Cong Ma
    Replies:
    19
    Views:
    2,098
  5. Hua Yanghao

    Python Descriptor as Instance Attribute

    Hua Yanghao, Jan 19, 2012, in forum: Python
    Replies:
    0
    Views:
    164
    Hua Yanghao
    Jan 19, 2012
Loading...

Share This Page