On Fri, 19 Dec 2003 00:44:28 -0300, Gabriel Genellina <ga*********@so ftlab.com.ar> wrote:
Hi
In the following code sample, I have:
- a Worker class, which could have a lot of methods and attributes. In
particular, it has a 'bar' attribute. This class can be modified as needed.
- a Base class (old-style) which defines a default class attribute 'bar'
too. I can't modify the source code of this class. Note that Workes does
not inherit from Base.
- a Derived class which must inherit from Base and is a wrapper around
Worker: it contains a Worker instance and delegates almost anything to it.
This class can be modified as needed too.
In what sense a "wrapper"?
For most attributes, as they are not found in the Derived instance's dict,
__getattr__ is called and the attribute is retrieved from the Worker instance.
Why do you (think you) need an explicit __getattr__ ? Usually there's better ways.
But for the 'bar' attribute, it is found in the Base class and just the
default value is returned. __getattr__ is never called.
I need to avoid this, and return Worker instance's value instead of Base's
default value.
That is, in the last line of the example, I want: d.bar == 'Hello'
How could it be done?
--- cut ---
# This class does the "real" work and I can modify it as needed
class Worker:
class Worker(object): def __init__(self, foo, bar):
self.foo = foo
self.bar = bar
# This is just a base class from which I must inherit but I can't modify it
class Base:
bar = None
# This is a wrapper for Worker and I can modify it.
# I want to get most attributes from Worker class
# but for 'bar' I always get the default from Base,
# its declaration there effectively hides the attribute
# from the delegated Worked instance.
class Derived(Base):
class Derived(Worker, Base):
"""never mind any methods at this point yet"""
def __init__(self, worker):
self.worker = worker
def __getattr__(sel f, name):
return getattr(self.wo rker, name)
w = Worker(1234, 'Hello')
print 'w.foo', w.foo # prints 1234
print 'w.bar', w.bar # prints Hello
d = Derived(w)
d = Derived(6578, 'Goodbye')
print 'd.foo',d.foo # prints 1234
print 'd.bar',d.bar # prints None, I want to get Hello
--- cut ---
Does this do anything for you? (you could inherit differently than below too, of course)
====< genellina.py >============== =============== =============== =============== ==============
# This class does the "real" work and I can modify it as needed
class Worker(object):
def __init__(self, foo, bar):
print 'Worker init: Initializing %s instance' % self.__class__. __name__
self.foo = foo
self.bar = bar
# This is just a base class from which I must inherit but I can't modify it
class Base:
def __init__(self,* args, **kw): print 'Base init:', args, kw
bar = None
baz = 'Base baz'
# This is a wrapper for Worker and I can modify it.
# I want to get most attributes from Worker class
##### why not just inherit them from ^^^^^^^^^^^^ ?
# but for 'bar' I always get the default from Base,
# its declaration there effectively hides the attribute
# from the delegated Worked instance.
class Derived(Worker, Base):
"""dummy until something to do"""
if __name__ == '__main__':
w = Worker(1234, 'Hello')
print 'w.foo of %s instance: %s' %(w.__class__._ _name__, w.foo) # prints 1234 now
print 'w.bar of %s instance: %s' %(w.__class__._ _name__, w.bar) # prints Hello now
d = Derived(5678, 'Goodbye') #w)
print 'd.foo of %s instance: %s' %(d.__class__._ _name__, d.foo) # prints 5678 now
print 'd.bar of %s instance: %s' %(d.__class__._ _name__, d.bar) # prints Goodbye now
print 'd.baz of/via %s instance: %s' %(d.__class__._ _name__, d.baz)
d.baz = 'd instance baz'
print 'd.baz of/via %s instance: %s' %(d.__class__._ _name__, d.baz)
=============== =============== =============== =============== =============== =============== ===
Result:
[21:52] C:\pywk\clp>gen ellina.py
Worker init: Initializing Worker instance
w.foo of Worker instance: 1234
w.bar of Worker instance: Hello
Worker init: Initializing Derived instance
d.foo of Derived instance: 5678
d.bar of Derived instance: Goodbye
d.baz of/via Derived instance: Base baz
d.baz of/via Derived instance: d instance baz
Or do you actually need to have different unknown types of workers so you can't inherit?
Regards,
Bengt Richter