derived classes and __getattr__

  • Thread starter Alexandru MoÈ™oi
  • Start date
A

Alexandru Moșoi

i'm facing the following problem:

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

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

class Derived(Base):
what_so_ever = dec(Base.what_so_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?
 
P

Peter Otten

Alexandru said:
i'm facing the following problem:

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

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

class Derived(Base):
what_so_ever = dec(Base.what_so_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__(type):
def __getattr__(self, 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_so_ever)

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

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

Peter
 
F

Fredrik Lundh

Alexandru said:
i'm facing the following problem:

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

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

class Derived(Base):
what_so_ever = dec(Base.what_so_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>
 
A

Alexandru Mosoi

__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__(type):
        def __getattr__(self, 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_so_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.
 
P

Peter Otten

Alexandru said:
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:
<class 'classattr.__metaclass__'>

If Python doesn't find an attribute in the instance it looks it up in the
class but not in the metaclass:
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
 
A

Alexandru Mosoi

That has nothing to do with inheritance:


<class 'classattr.__metaclass__'>

If Python doesn't find an attribute in the instance it looks it up in the
class but not in the metaclass:


<function <lambda> at 0x2b5f8028aa28>>>> Base().third

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__(self, attr):
return
functools.partial(Base.__metaclass__.__getattr__(self.__class__,
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)
 
B

Bruno Desthuilliers

Alexandru Mosoi a écrit :
(snip)
i somehow fixed the problem using:

def __getattr__(self, attr):
return
functools.partial(Base.__metaclass__.__getattr__(self.__class__,
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).
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,995
Messages
2,570,235
Members
46,821
Latest member
AleidaSchi

Latest Threads

Top