467,880 Members | 1,259 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 467,880 developers. It's quick & easy.

runtime inheritance (e.g. __new__, __metaclass__)

I try to work out how to use __new__ and metaclass (or __metaclass__)
mechanisms in order to change the base class at runtime. I haven't been
successful so far, however, even after also reading most of the relevant
documentation.

The most simple representation (an oversimplification indeed) of what
I'm trying to accomplish is this:

class Base1:
pass

class Base2:
pass

class Meta:
pass

class Good(Meta):
pass

What I want to achieve at runtime is this:

g1 = Good(Base1) # a Good object with base class Base1
g2 = Good(Base2) # a Good object with base class Base2

Of course, this oversimplified (pseudo-code) example will not work but
illustrates most clearly my idea. How can I come closest to realizing
this by using the above mechanisms?
Thanks

--Henk
--
------------------------------------------------------------------------------
The disclaimer that applies to e-mail from
TNO Physics and Electronics Laboratory
can be found on: http://www.tno.nl/disclaimer/email.html
------------------------------------------------------------------------------
Jul 18 '05 #1
  • viewed: 1786
Share:
3 Replies
H Jansen wrote:
I try to work out how to use __new__ and metaclass (or __metaclass__)
mechanisms in order to change the base class at runtime. I haven't been
successful so far, however, even after also reading most of the relevant
documentation.

The most simple representation (an oversimplification indeed) of what
I'm trying to accomplish is this:

class Base1:
pass

class Base2:
pass

class Meta:
pass

class Good(Meta):
pass

What I want to achieve at runtime is this:

g1 = Good(Base1) # a Good object with base class Base1
g2 = Good(Base2) # a Good object with base class Base2

Of course, this oversimplified (pseudo-code) example will not work but
illustrates most clearly my idea. How can I come closest to realizing
this by using the above mechanisms?

class Base1: pass .... class Base2: pass .... def Good(base): .... class Derived(base):
.... pass
.... return Derived()
.... g1 = Good(Base1)
g2 = Good(Base2)
isinstance(g1, Base1) True isinstance(g1, Base2) False isinstance(g2, Base1) False isinstance(g2, Base2)

True

:-)

Seriously, either too much information was lost in the simplification
process or you want to have instances of the same class with different
bases - which doesn't seem possible to me as the __bases__ attribute is in
the class, not the instance. On the other hand, changing base classes at
runtime is as simple as assigning __bases__.
__new__() can serve as a factory that returns objects of an arbitrary type,
but I don't consider that good style. Metaclasses - no idea where they
could enter the picture.
Peter

Jul 18 '05 #2
"H Jansen" <h.******@fel.tno.nl> wrote in message news:<ma*************************************@pyth on.org>...
What I want to achieve at runtime is this:

g1 = Good(Base1) # a Good object with base class Base1
g2 = Good(Base2) # a Good object with base class Base2


Peter's solution is clean (and the way I'd go) as long as you don't
mind Good being a function, not a class. If you need Good to be a
class, you could probably get what you want by changing the __bases__
attribute:
class Base1: .... def __init__(self):
.... print "Base1"
.... class Base2: .... def __init__(self):
.... print "Base2"
.... class Good: .... pass
.... Good.__bases__ = (Base1, )
Good() Base1
<__main__.Good instance at 0x00E6D738> Good.__bases__ = (Base2, )
Good() Base2
<__main__.Good instance at 0x00E6DC38>

Note that once you've changed the base classes of the Good class,
you'll have to change them back if you want the original behavior
again.

Or if you actually need different Good classes, you could try
something like:
class Base1(object): .... def __init__(self):
.... print "Base1"
.... class Base2(object): .... def __init__(self):
.... print "Base2"
.... class Good(object): .... pass
.... Good1 = type.__new__(type, "Good1", (Base1,), dict(Good.__dict__))
Good1() Base1
<__main__.Good1 object at 0x00E664F0> Good2 = type.__new__(type, "Good2", (Base2,), dict(Good.__dict__))
Good2() Base2
<__main__.Good2 object at 0x00E66450>

Note that type.__new__ requires a dict (not a dictproxy like the
__dict__ attribute), so I've copied the Good.__dict__ attribute
instead of having both classes reference the same one. This means
that if you have a class variable in Good (and therefore in Good1 and
Good2), if you modify it in Good1, it will not be modified in Good2,
e.g.:
Good1 = type.__new__(type, "Good1", (Base1,), dict(Good.__dict__))
Good2 = type.__new__(type, "Good2", (Base2,), dict(Good.__dict__))
Good1.x = 2
Good1.x 2 Good2.x 1

This may or may not be desirable.

This technique does seem to transfer any methods successfully:
class Good(object): .... def f(self, x):
.... print (self.__class__, x)
.... Good1 = type.__new__(type, "Good1", (Base1,), dict(Good.__dict__))
Good2 = type.__new__(type, "Good2", (Base2,), dict(Good.__dict__))
Good1().f(1) Base1
(<class '__main__.Good1'>, 1) Good2().f(2)

Base2
(<class '__main__.Good2'>, 2)

Steve
Jul 18 '05 #4

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

reply views Thread by John Hunter | last post: by
1 post views Thread by Antoine Pitrou | last post: by
11 posts views Thread by wijhierbeneden | last post: by
3 posts views Thread by | ov | last post: by
4 posts views Thread by news.microsoft.com | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.