Inheriting property functions

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

    #1

    Inheriting property functions

    Looking at this interactive session:
    >>class A(object):
    def __init__(self, a):
    self.a = a
    def get_a(self): return self.__a
    def set_a(self, new_a): self.__a = new_a
    a = property(get_a, set_a)

    >>class B(A):
    b = property(get_a, set_a)


    Traceback (most recent call last):
    File "<pyshell#1 1>", line 1, in <module>
    class B(A):
    File "<pyshell#1 1>", line 2, in B
    b = property(get_a, set_a)
    NameError: name 'get_a' is not defined
    >>class B(A):
    b = a


    Traceback (most recent call last):
    File "<pyshell#1 3>", line 1, in <module>
    class B(A):
    File "<pyshell#1 3>", line 2, in B
    b = a
    NameError: name 'a' is not defined
    >>>
    B isn't recognizing its inheritence of A's methods get_a and set_a
    during creation.

    Why am I doing this? For an object of type B, it makes more sense to
    reference the attribute 'b' than it does to reference the attribute
    'a', even though they are the same, in terms of readability.

    Is there any way to make this work as intended?

  • Dustan

    #2
    Re: Inheriting property functions


    Dustan wrote:
    Looking at this interactive session:
    >
    >class A(object):
    def __init__(self, a):
    self.a = a
    def get_a(self): return self.__a
    def set_a(self, new_a): self.__a = new_a
    a = property(get_a, set_a)
    >
    >
    >class B(A):
    b = property(get_a, set_a)
    >
    >
    Traceback (most recent call last):
    File "<pyshell#1 1>", line 1, in <module>
    class B(A):
    File "<pyshell#1 1>", line 2, in B
    b = property(get_a, set_a)
    NameError: name 'get_a' is not defined
    >class B(A):
    b = a
    >
    >
    Traceback (most recent call last):
    File "<pyshell#1 3>", line 1, in <module>
    class B(A):
    File "<pyshell#1 3>", line 2, in B
    b = a
    NameError: name 'a' is not defined
    >>
    >
    B isn't recognizing its inheritence of A's methods get_a and set_a
    during creation.
    >
    Why am I doing this? For an object of type B, it makes more sense to
    reference the attribute 'b' than it does to reference the attribute
    'a', even though they are the same, in terms of readability.
    Clarification: The code given is obviously not the actual code. I doubt
    it would really make a difference in types A and B given here, but for
    what I'm actually doing, it makes a big difference.
    Is there any way to make this work as intended?

    Comment

    • mdsteele@gmail.com

      #3
      Re: Inheriting property functions

      Dustan wrote:
      B isn't recognizing its inheritence of A's methods get_a and set_a
      during creation.
      >
      Why am I doing this? For an object of type B, it makes more sense to
      reference the attribute 'b' than it does to reference the attribute
      'a', even though they are the same, in terms of readability.
      >
      Is there any way to make this work as intended?
      Try this:
      >>class A(object):
      .... def __init__(self,a ):
      .... self.__a = a
      .... def get_a(self): return self.__a
      .... def set_a(self,new_ a): self.__a = new_a
      .... a = property(get_a, set_a)
      ....
      >>class B(A):
      .... b = property(A.get_ a,A.set_a)
      ....
      >>bar = B(5)
      >>bar.a
      5
      >>bar.b
      5

      The trouble is that get_a and set_a are attributes of the _class
      object_ A. Instances of A (and hence, instances of B) will see them,
      but the class B will not, so you have to point to them explicitly with
      A.get_a and A.set_a.

      Comment

      • Robert Kern

        #4
        Re: Inheriting property functions

        Dustan wrote:
        Looking at this interactive session:
        >
        >>>class A(object):
        def __init__(self, a):
        self.a = a
        def get_a(self): return self.__a
        def set_a(self, new_a): self.__a = new_a
        a = property(get_a, set_a)
        >
        >
        >>>class B(A):
        b = property(get_a, set_a)
        >
        >
        Traceback (most recent call last):
        File "<pyshell#1 1>", line 1, in <module>
        class B(A):
        File "<pyshell#1 1>", line 2, in B
        b = property(get_a, set_a)
        NameError: name 'get_a' is not defined
        >>>class B(A):
        b = a
        >
        >
        Traceback (most recent call last):
        File "<pyshell#1 3>", line 1, in <module>
        class B(A):
        File "<pyshell#1 3>", line 2, in B
        b = a
        NameError: name 'a' is not defined
        >
        B isn't recognizing its inheritence of A's methods get_a and set_a
        during creation.
        Inheritance really doesn't work that way. The code in the class suite gets
        executed in its own namespace that doesn't know anything about inheritance. The
        inheritance rules operate in attribute access on the class object later.

        Try this:

        class B(A):
        b = property(A.get_ a, A.set_a)

        or this:

        class B(A):
        b = A.a

        --
        Robert Kern

        "I have come to believe that the whole world is an enigma, a harmless enigma
        that is made terrible by our own mad attempt to interpret it as though it had
        an underlying truth."
        -- Umberto Eco

        Comment

        • mdsteele@gmail.com

          #5
          Re: Inheriting property functions

          Robert Kern wrote:
          Inheritance really doesn't work that way. The code in the class suite gets
          executed in its own namespace that doesn't know anything about inheritance. The
          inheritance rules operate in attribute access on the class object later.
          Right. That was what I should have said, but it came out wrong when I
          tried to say it. (-:

          -Matt

          Comment

          • Gabriel Genellina

            #6
            Re: Inheriting property functions

            At Friday 20/10/2006 19:49, Dustan wrote:
            >>class A(object):
            def get_a(self): return self.__a
            def set_a(self, new_a): self.__a = new_a
            a = property(get_a, set_a)

            >>class B(A):
            b = property(get_a, set_a)
            Use instead:

            b = property(A.get_ a, A.set_a)


            --
            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

            • Dustan

              #7
              Re: Inheriting property functions


              Robert Kern wrote:
              Dustan wrote:
              Looking at this interactive session:
              >>class A(object):
              def __init__(self, a):
              self.a = a
              def get_a(self): return self.__a
              def set_a(self, new_a): self.__a = new_a
              a = property(get_a, set_a)

              >>class B(A):
              b = property(get_a, set_a)


              Traceback (most recent call last):
              File "<pyshell#1 1>", line 1, in <module>
              class B(A):
              File "<pyshell#1 1>", line 2, in B
              b = property(get_a, set_a)
              NameError: name 'get_a' is not defined
              >>class B(A):
              b = a


              Traceback (most recent call last):
              File "<pyshell#1 3>", line 1, in <module>
              class B(A):
              File "<pyshell#1 3>", line 2, in B
              b = a
              NameError: name 'a' is not defined

              B isn't recognizing its inheritence of A's methods get_a and set_a
              during creation.
              >
              Inheritance really doesn't work that way. The code in the class suite gets
              executed in its own namespace that doesn't know anything about inheritance. The
              inheritance rules operate in attribute access on the class object later.
              >
              Try this:
              >
              class B(A):
              b = property(A.get_ a, A.set_a)
              >
              or this:
              >
              class B(A):
              b = A.a
              >
              --
              Robert Kern
              >
              "I have come to believe that the whole world is an enigma, a harmless enigma
              that is made terrible by our own mad attempt to interpret it as though it had
              an underlying truth."
              -- Umberto Eco
              Thanks for your help, and mdsteele's.

              Comment

              • Aahz

                #8
                Re: Inheriting property functions

                In article <1161383286.543 397.46700@m73g2 000cwd.googlegr oups.com>,
                Dustan <DustanGroups@g mail.comwrote:
                >
                >>>class A(object):
                > def __init__(self, a):
                > self.a = a
                > def get_a(self): return self.__a
                > def set_a(self, new_a): self.__a = new_a
                > a = property(get_a, set_a)
                >
                >
                >>>class B(A):
                > b = property(get_a, set_a)
                BTW, since you're almost certainly going to run into this quickly given
                the direction your code is taking (and also to fix some bugs):

                class A(object):
                def __init__(self, a):
                self._a = a

                def get_a(self):
                return self._a

                def _get_a(self):
                return self.get_a()

                def set_a(self, new_a):
                self._a = new_a

                def _set_a(self, new_a):
                self.set_a(new_ a)

                a = property(_get_a , _set_a)

                class B(A):
                def get_a(self):
                return str(self._a)

                Thank Alex Martelli for this demonstration that programming is all built
                on one basic trick: add another layer of indirection. However, I leave
                you to figure out on your own why this is better.

                Note carefully that I changed __a to _a. You almost never want to use
                double-underscore private names because of the way they cause problems
                with inheritance.

                PS: Please do NOT post code with TABs
                --
                Aahz (aahz@pythoncra ft.com) <* http://www.pythoncraft.com/

                "If you don't know what your program is supposed to do, you'd better not
                start writing it." --Dijkstra

                Comment

                • Diez B. Roggisch

                  #9
                  Re: Inheriting property functions

                  Dustan schrieb:
                  Looking at this interactive session:
                  >
                  >>>class A(object):
                  def __init__(self, a):
                  self.a = a
                  def get_a(self): return self.__a
                  def set_a(self, new_a): self.__a = new_a
                  a = property(get_a, set_a)
                  >
                  >
                  >>>class B(A):
                  b = property(get_a, set_a)
                  >
                  >
                  Traceback (most recent call last):
                  File "<pyshell#1 1>", line 1, in <module>
                  class B(A):
                  File "<pyshell#1 1>", line 2, in B
                  b = property(get_a, set_a)
                  NameError: name 'get_a' is not defined
                  >>>class B(A):
                  b = a
                  >
                  >
                  Traceback (most recent call last):
                  File "<pyshell#1 3>", line 1, in <module>
                  class B(A):
                  File "<pyshell#1 3>", line 2, in B
                  b = a
                  NameError: name 'a' is not defined
                  >
                  B isn't recognizing its inheritence of A's methods get_a and set_a
                  during creation.
                  >
                  Why am I doing this? For an object of type B, it makes more sense to
                  reference the attribute 'b' than it does to reference the attribute
                  'a', even though they are the same, in terms of readability.
                  I think you are having a code smell here. However, this is how you do it:

                  class B(A):
                  b = A.a


                  Diez

                  Comment

                  • Bruno Desthuilliers

                    #10
                    Re: Inheriting property functions

                    mdsteele@gmail. com a écrit :
                    (snip)
                    The trouble is that get_a and set_a are attributes of the _class
                    object_ A. Instances of A (and hence, instances of B) will see them,
                    but the class B will not,
                    Yes it does:
                    >>class A(object):
                    .... aa = "aa"
                    ....
                    >>class B(A):pass
                    ....
                    >>B.aa
                    'aa'
                    >>>
                    so you have to point to them explicitly with
                    A.get_a and A.set_a.
                    Actually, while the solution is good, the explanation is wrong.

                    Comment

                    Working...