per instance descriptors

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Simon Bunker

    #1

    per instance descriptors

    Hi I have code similar to this:

    class Input(object):

    def __init__(self, val):
    self.value = val

    def __get__(self, obj, objtype):
    return self.value

    def __set__(self, obj, val):
    # do some checking... only accept floats etc
    self.value = val

    class Node(object):

    a = Input(1)
    b = Input(2)

    I realise that a and b are now class attributes - however I want to do this:

    node1 = Node()
    node2 = Node()

    node1.a = 3
    node.b = 4

    And have them keep these values per instance. However now node1.a is 4
    when it should be 3.

    Basically I want to have the Input class as a gateway that does lots of
    checking when the attibute is assigned or read.

    I have had a look at __getattribute_ _(), but this gets very ugly as I
    have to check if the attribute is an Input class or not.

    Also I don't think property() is appropriate is it? All of the
    attributes will essentially be doing the same thing - they should not
    have individual set/get commands.

    Is there any way of doing this nicely in Python?

    thanks

    Simon
  • George Sakkis

    #2
    Re: per instance descriptors

    Simon Bunker wrote:
    Hi I have code similar to this:
    >
    class Input(object):
    >
    def __init__(self, val):
    self.value = val
    >
    def __get__(self, obj, objtype):
    return self.value
    >
    def __set__(self, obj, val):
    # do some checking... only accept floats etc
    self.value = val
    >
    class Node(object):
    >
    a = Input(1)
    b = Input(2)
    >
    I realise that a and b are now class attributes - however I want to do this:
    >
    node1 = Node()
    node2 = Node()
    >
    node1.a = 3
    node.b = 4
    >
    And have them keep these values per instance. However now node1.a is 4
    when it should be 3.
    >
    Basically I want to have the Input class as a gateway that does lots of
    checking when the attibute is assigned or read.
    >
    I have had a look at __getattribute_ _(), but this gets very ugly as I
    have to check if the attribute is an Input class or not.
    >
    Also I don't think property() is appropriate is it? All of the
    attributes will essentially be doing the same thing - they should not
    have individual set/get commands.
    >
    Is there any way of doing this nicely in Python?
    What about __setattr__ ? At least from your example, checking happens
    only when you set an attribute. If not, post a more representative
    sample of what you're trying to do.

    George

    Comment

    • Gabriel Genellina

      #3
      Re: per instance descriptors

      At Thursday 7/12/2006 01:58, George Sakkis wrote:
      >Simon Bunker wrote:
      >
      Basically I want to have the Input class as a gateway that does lots of
      checking when the attibute is assigned or read.

      I have had a look at __getattribute_ _(), but this gets very ugly as I
      have to check if the attribute is an Input class or not.

      Also I don't think property() is appropriate is it? All of the
      attributes will essentially be doing the same thing - they should not
      have individual set/get commands.

      Is there any way of doing this nicely in Python?
      >
      >What about __setattr__ ? At least from your example, checking happens
      >only when you set an attribute. If not, post a more representative
      >sample of what you're trying to do.
      Or search the Python Cookbook - there are zillions of variants on how
      to manage properties (using inner classes, using decorators, using
      closures, using ...). Traits (code.enthought .com) may be useful too.


      --
      Gabriel Genellina
      Softlab SRL

      _______________ _______________ _______________ _____
      Correo Yahoo!
      Espacio para todos tus mensajes, antivirus y antispam ¡gratis!
      ¡Abrí tu cuenta ya! - http://correo.yahoo.com.ar

      Comment

      • Carl Banks

        #4
        Re: per instance descriptors


        Simon Bunker wrote:
        Hi I have code similar to this:
        >
        class Input(object):
        >
        def __init__(self, val):
        self.value = val
        >
        def __get__(self, obj, objtype):
        return self.value
        >
        def __set__(self, obj, val):
        # do some checking... only accept floats etc
        self.value = val
        >
        class Node(object):
        >
        a = Input(1)
        b = Input(2)
        >
        I realise that a and b are now class attributes - however I want to do this:
        >
        node1 = Node()
        node2 = Node()
        >
        node1.a = 3
        node2.b = 4
        >
        And have them keep these values per instance. However now node1.a is 4
        when it should be 3.
        [snip]
        Is there any way of doing this nicely in Python?
        The easiest way is to store the value in a hidden attribute of the
        object. For instance:

        class Input(object):
        def __init__(self,d efault,name):
        self.default = default
        self.name = name # or, create a name automatically
        def __get__(self,ob j,objtype):
        return getattr(obj,sel f.name,self.def ault)
        def __set__(self,ob j,value):
        setattr(obj,sel f.name,value)

        class Node(object):
        a = Input(1,"_a")
        b = Input(2,"_b")


        Carl Banks

        Comment

        • simon@rendermania.com

          #5
          Re: per instance descriptors


          George Sakkis wrote:
          Simon Bunker wrote:
          >
          Hi I have code similar to this:

          class Input(object):

          def __init__(self, val):
          self.value = val

          def __get__(self, obj, objtype):
          return self.value

          def __set__(self, obj, val):
          # do some checking... only accept floats etc
          self.value = val

          class Node(object):

          a = Input(1)
          b = Input(2)

          I realise that a and b are now class attributes - however I want to do this:

          node1 = Node()
          node2 = Node()

          node1.a = 3
          node.b = 4

          And have them keep these values per instance. However now node1.a is 4
          when it should be 3.

          Basically I want to have the Input class as a gateway that does lots of
          checking when the attibute is assigned or read.

          I have had a look at __getattribute_ _(), but this gets very ugly as I
          have to check if the attribute is an Input class or not.

          Also I don't think property() is appropriate is it? All of the
          attributes will essentially be doing the same thing - they should not
          have individual set/get commands.

          Is there any way of doing this nicely in Python?
          >
          What about __setattr__ ? At least from your example, checking happens
          only when you set an attribute. If not, post a more representative
          sample of what you're trying to do.
          >
          George
          Yes, but I am setting it in the Node class aren't I? Wouldn't I need to
          define __setattr__() in class Node rather than class Input? I don't
          want to do this. Or am I getting confused here?

          thanks

          Simon

          Comment

          • George Sakkis

            #6
            Re: per instance descriptors

            simon@renderman ia.com wrote:
            George Sakkis wrote:
            Simon Bunker wrote:
            Hi I have code similar to this:
            >
            class Input(object):
            >
            def __init__(self, val):
            self.value = val
            >
            def __get__(self, obj, objtype):
            return self.value
            >
            def __set__(self, obj, val):
            # do some checking... only accept floats etc
            self.value = val
            >
            class Node(object):
            >
            a = Input(1)
            b = Input(2)
            >
            I realise that a and b are now class attributes - however I want to do this:
            >
            node1 = Node()
            node2 = Node()
            >
            node1.a = 3
            node.b = 4
            >
            And have them keep these values per instance. However now node1.a is 4
            when it should be 3.
            >
            Basically I want to have the Input class as a gateway that does lots of
            checking when the attibute is assigned or read.
            >
            I have had a look at __getattribute_ _(), but this gets very ugly as I
            have to check if the attribute is an Input class or not.
            >
            Also I don't think property() is appropriate is it? All of the
            attributes will essentially be doing the same thing - they should not
            have individual set/get commands.
            >
            Is there any way of doing this nicely in Python?
            What about __setattr__ ? At least from your example, checking happens
            only when you set an attribute. If not, post a more representative
            sample of what you're trying to do.

            George
            >
            Yes, but I am setting it in the Node class aren't I? Wouldn't I need to
            define __setattr__() in class Node rather than class Input? I don't
            want to do this. Or am I getting confused here?
            Yes, __setattr__ would be defined in Node and Input would go. It seems
            to me that the only reason you introduced Input was to implement this
            controlled attribute access, and as you see it doesn't work as you want
            it to. Why not define Node.__setattr_ _ ?

            George

            Comment

            • Simon Bunker

              #7
              Re: per instance descriptors

              George Sakkis wrote:
              simon@renderman ia.com wrote:
              >
              >
              >>George Sakkis wrote:
              >>
              >>>Simon Bunker wrote:
              >>>
              >>>
              >>>>Hi I have code similar to this:
              >>>>
              >>>>class Input(object):
              >>>>
              >>> def __init__(self, val):
              >>> self.value = val
              >>>>
              >>> def __get__(self, obj, objtype):
              >>> return self.value
              >>>>
              >>> def __set__(self, obj, val):
              >>> # do some checking... only accept floats etc
              >>> self.value = val
              >>>>
              >>>>class Node(object):
              >>>>
              >>>> a = Input(1)
              >>>> b = Input(2)
              >>>>
              >>>>I realise that a and b are now class attributes - however I want to do this:
              >>>>
              >>>>node1 = Node()
              >>>>node2 = Node()
              >>>>
              >>>>node1.a = 3
              >>>>node.b = 4
              >>>>
              >>>>And have them keep these values per instance. However now node1.a is 4
              >>>>when it should be 3.
              >>>>
              >>>>Basically I want to have the Input class as a gateway that does lots of
              >>>>checking when the attibute is assigned or read.
              >>>>
              >>>>I have had a look at __getattribute_ _(), but this gets very ugly as I
              >>>>have to check if the attribute is an Input class or not.
              >>>>
              >>>>Also I don't think property() is appropriate is it? All of the
              >>>>attribute s will essentially be doing the same thing - they should not
              >>>>have individual set/get commands.
              >>>>
              >>>>Is there any way of doing this nicely in Python?
              >>>
              >>>What about __setattr__ ? At least from your example, checking happens
              >>>only when you set an attribute. If not, post a more representative
              >>>sample of what you're trying to do.
              >>>
              >>>George
              >>
              >>Yes, but I am setting it in the Node class aren't I? Wouldn't I need to
              >>define __setattr__() in class Node rather than class Input? I don't
              >>want to do this. Or am I getting confused here?
              >
              >
              Yes, __setattr__ would be defined in Node and Input would go. It seems
              to me that the only reason you introduced Input was to implement this
              controlled attribute access, and as you see it doesn't work as you want
              it to. Why not define Node.__setattr_ _ ?
              >
              George
              >
              The __setattr__ approach is what I am hoping to avoid.

              Having the input class means that I just need to assign a class to an
              attribute rather than having to filter each attribute name - really
              annoying as there will be several classes similar to Node with different
              attributes, but which should be handled in the same way.

              Frankly descriptors seems exactly what I want - but having them as class
              attributes makes them completely useless!

              Simon

              Comment

              • Simon Bunker

                #8
                Re: per instance descriptors

                Carl Banks wrote:
                Simon Bunker wrote:
                >
                >>Hi I have code similar to this:
                >>
                >>class Input(object):
                >>
                > def __init__(self, val):
                > self.value = val
                >>
                > def __get__(self, obj, objtype):
                > return self.value
                >>
                > def __set__(self, obj, val):
                > # do some checking... only accept floats etc
                > self.value = val
                >>
                >>class Node(object):
                >>
                >> a = Input(1)
                >> b = Input(2)
                >>
                >>I realise that a and b are now class attributes - however I want to do this:
                >>
                >>node1 = Node()
                >>node2 = Node()
                >>
                >>node1.a = 3
                >>node2.b = 4
                >>
                >>And have them keep these values per instance. However now node1.a is 4
                >>when it should be 3.
                >
                [snip]
                >
                >>Is there any way of doing this nicely in Python?
                >
                >
                The easiest way is to store the value in a hidden attribute of the
                object. For instance:
                >
                class Input(object):
                def __init__(self,d efault,name):
                self.default = default
                self.name = name # or, create a name automatically
                def __get__(self,ob j,objtype):
                return getattr(obj,sel f.name,self.def ault)
                def __set__(self,ob j,value):
                setattr(obj,sel f.name,value)
                >
                class Node(object):
                a = Input(1,"_a")
                b = Input(2,"_b")
                >
                >
                Carl Banks
                >
                This does seem the easiest way - but also a bit of a hack. Would it work
                to assign to instance variables - each the class attribute sets the
                instance attribute with the same name? Or would that not work?

                Simon

                Comment

                Working...