derived classes and __getattr__

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • =?UTF-8?Q?Alexandru_Mo=C8=99oi?=

    derived classes and __getattr__

    i'm facing the following problem:

    class Base(object):
    def __getattr__(sel f, attr): return lambda x: attr + '_' + x

    def dec(callable):
    return lambda *args: 'dec_' + callable(*args)

    class Derived(Base):
    what_so_ever = dec(Base.what_s o_ever) # wrong, base doesn't have
    what_so_ever
    mumu = dec(Base.mumu) # wrong, base
    doesn't have mumu

    any idea how to do this?
  • Peter Otten

    #2
    Re: derived classes and __getattr__

    Alexandru Moșoi wrote:
    i'm facing the following problem:
    >
    class Base(object):
    def __getattr__(sel f, attr): return lambda x: attr + '_' + x
    >
    def dec(callable):
    return lambda *args: 'dec_' + callable(*args)
    >
    class Derived(Base):
    what_so_ever = dec(Base.what_s o_ever) # wrong, base doesn't have
    what_so_ever
    mumu = dec(Base.mumu) # wrong, base
    doesn't have mumu
    >
    any idea how to do this?
    __getattr__() is defined in the class to create instance attributes on the
    fly. If you want class attributes you have to put the __getattr__() method
    into the class of the class, or "metaclass" :

    class Base(object):
    class __metaclass__(t ype):
    def __getattr__(sel f, attr):
    return lambda self, x: attr + '_' + x

    def dec(callable):
    return lambda *args: 'dec_' + callable(*args)

    class Derived(Base):
    what_so_ever = dec(Base.what_s o_ever)

    d = Derived()
    print d.what_so_ever( "42")

    I don't see how you can turn this into something useful...

    Peter

    Comment

    • Fredrik Lundh

      #3
      Re: derived classes and __getattr__

      Alexandru Mos,oi wrote:
      i'm facing the following problem:
      >
      class Base(object):
      def __getattr__(sel f, attr): return lambda x: attr + '_' + x
      >
      def dec(callable):
      return lambda *args: 'dec_' + callable(*args)
      >
      class Derived(Base):
      what_so_ever = dec(Base.what_s o_ever) # wrong, base doesn't have
      what_so_ever
      mumu = dec(Base.mumu) # wrong, base
      doesn't have mumu
      >
      any idea how to do this?
      ever thought of using Python to write Python programs?

      </F>

      Comment

      • Alexandru  Mosoi

        #4
        Re: derived classes and __getattr__

        On Sep 5, 11:47 am, Peter Otten <__pete...@web. dewrote:
        Alexandru Moșoi wrote:
        i'm facing the following problem:
        >
        class Base(object):
          def __getattr__(sel f, attr): return lambda x: attr + '_' + x
        >
        def dec(callable):
          return lambda *args: 'dec_' + callable(*args)
        >
        class Derived(Base):
           what_so_ever = dec(Base.what_s o_ever) # wrong, base doesn't have
        what_so_ever
           mumu = dec(Base.mumu)                         # wrong, base
        doesn't have mumu
        >
        any idea how to do this?
        >
        __getattr__() is defined in the class to create instance attributes on the
        fly. If you want class attributes you have to put the __getattr__() method
        into the class of the class, or "metaclass" :
        >
        class Base(object):
            class __metaclass__(t ype):
                def __getattr__(sel f, attr):
                    return lambda self, x: attr + '_' + x
        >
        def dec(callable):
            return lambda *args: 'dec_' + callable(*args)
        >
        class Derived(Base):
           what_so_ever = dec(Base.what_s o_ever)
        >
        d = Derived()
        print d.what_so_ever( "42")
        >
        I don't see how you can turn this into something useful...
        >
        Peter
        10x. it works. however I have another small problem. now,
        d.third('blah') doesn't work because instance d doesn't have 'third'
        attribute. I was expecting derived class to inherit the metaclass as
        well, but it didn't.

        Comment

        • Peter Otten

          #5
          Re: derived classes and __getattr__

          Alexandru Mosoi wrote:
          On Sep 5, 11:47 am, Peter Otten <__pete...@web. dewrote:
          >Alexandru Moșoi wrote:
          i'm facing the following problem:
          >>
          class Base(object):
          def __getattr__(sel f, attr): return lambda x: attr + '_' + x
          >>
          def dec(callable):
          return lambda *args: 'dec_' + callable(*args)
          >>
          class Derived(Base):
          what_so_ever = dec(Base.what_s o_ever) # wrong, base doesn't have
          what_so_ever
          mumu = dec(Base.mumu)                          # wrong, base
          doesn't have mumu
          >>
          any idea how to do this?
          >>
          >__getattr__( ) is defined in the class to create instance attributes on
          >the fly. If you want class attributes you have to put the __getattr__()
          >method into the class of the class, or "metaclass" :
          >>
          >class Base(object):
          >class __metaclass__(t ype):
          >def __getattr__(sel f, attr):
          >return lambda self, x: attr + '_' + x
          >>
          >def dec(callable):
          >return lambda *args: 'dec_' + callable(*args)
          >>
          >class Derived(Base):
          >what_so_ever = dec(Base.what_s o_ever)
          >>
          >d = Derived()
          >print d.what_so_ever( "42")
          >>
          >I don't see how you can turn this into something useful...
          >>
          >Peter
          >
          10x. it works. however I have another small problem. now,
          d.third('blah') doesn't work because instance d doesn't have 'third'
          attribute. I was expecting derived class to inherit the metaclass as
          well, but it didn't.
          That has nothing to do with inheritance:
          >>type(Derive d)
          <class 'classattr.__me taclass__'>

          If Python doesn't find an attribute in the instance it looks it up in the
          class but not in the metaclass:
          >>Base.third
          <function <lambdaat 0x2b5f8028aa28>
          >>Base().thir d
          Traceback (most recent call last):
          File "<stdin>", line 1, in <module>
          AttributeError: 'Base' object has no attribute 'third'

          I think you should go back to the drawing board now and look for a simpler
          approach to solve your actual problem...

          Peter

          Comment

          • Michele Simionato

            #6
            Re: derived classes and __getattr__

            On Sep 5, 11:46 am, Alexandru Mosoi <brtz...@gmail. comwrote:
            I have another small problem. now,
            d.third('blah') doesn't work because instance d doesn't have 'third'
            attribute. I was expecting derived class to inherit the metaclass as
            well, but it didn't.
            Yep, it is explained here: https://www.ibm.com/developerworks/l...ary/l-pymeta2/
            It would help if you told us the real problem you are trying to solve.

            Comment

            • Alexandru  Mosoi

              #7
              Re: derived classes and __getattr__

              On Sep 5, 1:13 pm, Peter Otten <__pete...@web. dewrote:
              Alexandru  Mosoi wrote:
              On Sep 5, 11:47 am, Peter Otten <__pete...@web. dewrote:
              Alexandru Moșoi wrote:
              i'm facing the following problem:
              >
              class Base(object):
              def __getattr__(sel f, attr): return lambda x: attr + '_' + x
              >
              def dec(callable):
              return lambda *args: 'dec_' + callable(*args)
              >
              class Derived(Base):
              what_so_ever = dec(Base.what_s o_ever) # wrong, base doesn't have
              what_so_ever
              mumu = dec(Base.mumu)                          # wrong, base
              doesn't have mumu
              >
              any idea how to do this?
              >
              __getattr__() is defined in the class to create instance attributes on
              the fly. If you want class attributes you have to put the __getattr__()
              method into the class of the class, or "metaclass" :
              >
              class Base(object):
              class __metaclass__(t ype):
              def __getattr__(sel f, attr):
              return lambda self, x: attr + '_' + x
              >
              def dec(callable):
              return lambda *args: 'dec_' + callable(*args)
              >
              class Derived(Base):
              what_so_ever = dec(Base.what_s o_ever)
              >
              d = Derived()
              print d.what_so_ever( "42")
              >
              I don't see how you can turn this into something useful...
              >
              Peter
              >
              10x. it works. however I have another small problem. now,
              d.third('blah') doesn't work because instance d doesn't have 'third'
              attribute. I was expecting derived class to inherit the metaclass as
              well, but it didn't.
              >
              That has nothing to do with inheritance:
              >
              >type(Derived )
              >
              <class 'classattr.__me taclass__'>
              >
              If Python doesn't find an attribute in the instance it looks it up in the
              class but not in the metaclass:
              >
              >Base.third
              >
              <function <lambdaat 0x2b5f8028aa28> >>Base().thir d
              >
              Traceback (most recent call last):
                File "<stdin>", line 1, in <module>
              AttributeError: 'Base' object has no attribute 'third'
              >
              I think you should go back to the drawing board now and look for a simpler
              approach to solve your actual problem...
              >
              Peter

              i somehow fixed the problem using:

              def __getattr__(sel f, attr):
              return
              functools.parti al(Base.__metac lass__.__getatt r__(self.__clas s__,
              attr), self)

              however this looks ugly enough to look for another solution. i still
              have one more question: why do I have to bind self? (without which
              functions fail expecting an instance)

              Comment

              • Bruno Desthuilliers

                #8
                Re: derived classes and __getattr__

                Alexandru Mosoi a écrit :
                (snip)
                i somehow fixed the problem using:
                >
                def __getattr__(sel f, attr):
                return
                functools.parti al(Base.__metac lass__.__getatt r__(self.__clas s__,
                attr), self)
                >
                however this looks ugly enough to look for another solution. i still
                have one more question: why do I have to bind self? (without which
                functions fail expecting an instance)
                Because the partial type doesn't implement the descriptor protocol
                (which is implemented by function type to return a method).

                Comment

                Working...