descriptor problems

Discussion in 'Python' started by Gary Stephenson, Sep 14, 2006.

  1. I want to define a class-level attribute that will be shared by all
    subclasses. That is, I want this class, every subclass of this class, every
    instance of this class and every instance of every subclass to be able to
    read and write to the _same_ slot/variable. But I can't figure out how to
    do it.

    My attempts so far have led me to using a descriptor as follow, but it
    doesn't get me where I want to be:

    class sharedClassVar(object):
    def __init__(self,x=None):
    print "creating"
    self.value = x
    def __get__(self,ob,cls):
    print "getting"
    return self.value
    def __set__(self,ob,x):
    print "setting"
    self.value = x


    class A( object ):
    # install it like this I guess:
    cls2 = sharedClassVar(5)

    class B( A ):
    pass

    print A.cls2 # so far so good
    o = A()
    o2 = B()
    print o.cls2 # ok
    print o2.cls2 # ok
    o.cls2 = 2
    print B.cls2 # perfect
    print o2.cls2 # ""
    o2.cls2 = 3
    print A.cls2 # ""
    print o.cls2 # ""

    # but I need to be able to update the value through the class
    # how do I do it?
    A.cls2 = 4 # whoops - we just overwrote the descriptor with an integer

    A.cls2.__set__(None,4) # AttributeError: 'int' object has no attribute
    '__set__'
    Gary Stephenson, Sep 14, 2006
    #1
    1. Advertising

  2. Gary Stephenson

    Peter Otten Guest

    Gary Stephenson wrote:

    > I want to define a class-level attribute that will be shared by all
    > subclasses. That is, I want this class, every subclass of this class,
    > every instance of this class and every instance of every subclass to be
    > able to
    > read and write to the _same_ slot/variable. But I can't figure out how to
    > do it.


    class A:
    class __metaclass__(type):
    _shared = 42
    def get_shared(self):
    return self.__class__._shared
    def set_shared(self, value):
    print "%r --> %r" % (self._shared, value)
    self.__class__._shared = value
    shared = property(get_shared, set_shared)

    def get_shared(self):
    return self.__class__.shared
    def set_shared(self, value):
    self.__class__.shared = value
    shared = property(get_shared, set_shared)

    Does that what you want?

    Peter
    Peter Otten, Sep 14, 2006
    #2
    1. Advertising

  3. Gary Stephenson wrote:
    > # but I need to be able to update the value through the class
    > # how do I do it?
    > A.cls2 = 4 # whoops - we just overwrote the descriptor with an integer
    >
    > A.cls2.__set__(None,4) # AttributeError: 'int' object has no attribute
    > '__set__'


    You need to define the descriptor at the metaclass level too.

    Michele Simionato
    Michele Simionato, Sep 14, 2006
    #3
  4. "Peter Otten" <> wrote in message
    news:eeb8oq$79d$01$-online.com...
    > Gary Stephenson wrote:
    >
    >> I want to define a class-level attribute that will be shared by all
    >> subclasses. That is, I want this class, every subclass of this class,
    >> every instance of this class and every instance of every subclass to be
    >> able to
    >> read and write to the _same_ slot/variable. But I can't figure out how
    >> to
    >> do it.

    >
    > class A:
    > class __metaclass__(type):
    > _shared = 42
    > def get_shared(self):
    > return self.__class__._shared
    > def set_shared(self, value):
    > print "%r --> %r" % (self._shared, value)
    > self.__class__._shared = value
    > shared = property(get_shared, set_shared)
    >
    > def get_shared(self):
    > return self.__class__.shared
    > def set_shared(self, value):
    > self.__class__.shared = value
    > shared = property(get_shared, set_shared)
    >
    > Does that what you want?


    It certainly does! But I need to figure out how to package it up a bit more
    elegantly. I'd prefer not to have to define a separate metaclass for each
    class if I could avoid it. hmmm ..... The following is what I eventually
    came up with, which is exactly what I was after:

    class valueDescriptor(object):
    def __init__(self,x=None):
    self.value = x
    def __get__(self,ob,cls=None):
    return self.value
    def __set__(self,ob,x):
    self.value = x

    class Ameta(type):
    def createShared( cls, nm, initValue=None ):
    o = valueDescriptor(initValue)
    setattr( cls,nm, o )
    setattr( cls.__class__,nm, o )

    class A:
    __metaclass__ = Ameta

    class B( A ):
    A.createShared("cls2",1)


    Many thanks,

    gary
    Gary Stephenson, Sep 15, 2006
    #4
    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. Patrick LeBoutillier

    Read/Write IO on socket file descriptor?

    Patrick LeBoutillier, Jul 19, 2003, in forum: Perl
    Replies:
    0
    Views:
    3,063
    Patrick LeBoutillier
    Jul 19, 2003
  2. Geoff Cox

    why "bad file descriptor"?

    Geoff Cox, Dec 4, 2005, in forum: Perl
    Replies:
    1
    Views:
    8,629
    Geoff Cox
    Dec 5, 2005
  3. Jeff Kelm
    Replies:
    1
    Views:
    2,825
    Jeff Kelm
    Sep 11, 2003
  4. Lindsay Pallickal
    Replies:
    4
    Views:
    15,209
    suzanka
    Jan 31, 2008
  5. Mark Sizzler
    Replies:
    0
    Views:
    441
    Mark Sizzler
    Oct 19, 2004
Loading...

Share This Page