473,396 Members | 2,061 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

Mix-In Class Methods At Run-Time

Hi all. If I have an instance of class A, called say foo, and I need to
mix-in the functions and variables of another class (class B) to this
instance at runtime, how do I do it? In other words, I want to make foo
an instance of an anonymous and temporary class that inherits its
functionality from classes A and B, while at the same time I want the
pre-existing contents of foo to remain intact. Possible in Python?

Thanks....

Jun 24 '06 #1
8 1609
I think it's possible, most of such kind of things are possible with
Python.
I'm not an expert yet in such kind of things, so this can be a starting
point for you (note the shadowing of m2, the class docstrings, etc).
Other people can give you something better or more correct.

class A:
def m1(self): return "m1"
def m2(self): return "m2"

class B:
def m3(self): return "m3"

class P:
def m2(self): return "m2b"
def m4(self): return"m4"

def mixin(object, *classes):
class NewClass(object.__class__):
pass
for C in classes:
NewClass.__dict__.update(C.__dict__)
object.__class__ = NewClass

foo = P()
print "Before:"
print "foo.__class__.__dict__.keys():", foo.__class__.__dict__.keys()
print "P.__dict__.keys():", P.__dict__.keys()
print "foo.m2():", foo.m2()
print "foo.m4():", foo.m4(), "\n"

mixin(foo, A, B)

print "After:"
print "foo.__class__.__dict__.keys():", foo.__class__.__dict__.keys()
print "P.__dict__.keys():", P.__dict__.keys()
print "foo.m1():", foo.m1()
print "foo.m2():", foo.m2()
print "foo.m3():", foo.m3()
print "foo.m4():", foo.m4()

Bye,
bearophile

Jun 25 '06 #2
This looks excellent bearophile, but I'm having trouble understanding
some things. Perhaps you can help wipe clean my ignorance. Firstly, I
thought __classes__ was a read-only attribute? Secondly, what is a
"dictproxy object" and why won't the following code work:

class Cat:
def meow(self):
print "meow"
def MixIn(object, *classes):
temp = type('ClassPie', (object.__class__,) + classes, {})
temp.__dict__.update([object.__dict__])
NewClass = MixIn(Cat(), C, D)
test = NewClass()

__dict__, to my understanding, is suppose to be a dictionary, but
Python keeps telling me it's a 'dictproxy' object and that it has no
attribute 'update'. Why is this?

Thanks.
be************@lycos.com wrote:
I think it's possible, most of such kind of things are possible with
Python.
I'm not an expert yet in such kind of things, so this can be a starting
point for you (note the shadowing of m2, the class docstrings, etc).
Other people can give you something better or more correct.

class A:
def m1(self): return "m1"
def m2(self): return "m2"

class B:
def m3(self): return "m3"

class P:
def m2(self): return "m2b"
def m4(self): return"m4"

def mixin(object, *classes):
class NewClass(object.__class__):
pass
for C in classes:
NewClass.__dict__.update(C.__dict__)
object.__class__ = NewClass

foo = P()
print "Before:"
print "foo.__class__.__dict__.keys():", foo.__class__.__dict__.keys()
print "P.__dict__.keys():", P.__dict__.keys()
print "foo.m2():", foo.m2()
print "foo.m4():", foo.m4(), "\n"

mixin(foo, A, B)

print "After:"
print "foo.__class__.__dict__.keys():", foo.__class__.__dict__.keys()
print "P.__dict__.keys():", P.__dict__.keys()
print "foo.m1():", foo.m1()
print "foo.m2():", foo.m2()
print "foo.m3():", foo.m3()
print "foo.m4():", foo.m4()

Bye,
bearophile


Jun 25 '06 #3
Okay, while I'd still like to know the answer(s) to my earlier
question(s), I've mostly solved my problem thanks to bearophile and my
own learning. An example:

class Cat(object):
def __init__(self):
self.love = 0
def meow(self):
print "meow"
class Dog(object):
def bark(self):
print "bark"
class Bat(object):
def scream(self):
print "scream"
def Mixin(object, *classes):
NewClass = type('Mixin', (object.__class__,) + classes, {})
newobj = NewClass()
newobj.__dict__.update(object.__dict__)
return newobj
mycat = Cat()
mycat.love = 4
mycat = Mixin(mycat, Dog, Bat)
print mycat.__dict__, mycat.__class__, mycat.__class__.__bases__
print dir(mycat)

Two additional questions though: 1) is there a way for a function to
get a reference to its caller automatically (as in, without the caller
having to pass it in)? and 2) what's the reason to use newstyle classes
versus the old? In order to create the dynamic class "NewClass" in the
code above I called type() but that requires at least one new style
class as a base. Thus, I had to have at least one of my animals inherit
from "object" and this seemed a nuisance since I don't at this point
know what the benefit of "newstyle" classes is. I was going to just use
the new module and classobj() but I read somewhere that that was
unadvisable and newstyle classes should be used in new code. ...

Thank you.

Cheers,
DigiO

di*************@gmail.com wrote:
This looks excellent bearophile, but I'm having trouble understanding
some things. Perhaps you can help wipe clean my ignorance. Firstly, I
thought __classes__ was a read-only attribute? Secondly, what is a
"dictproxy object" and why won't the following code work:

class Cat:
def meow(self):
print "meow"
def MixIn(object, *classes):
temp = type('ClassPie', (object.__class__,) + classes, {})
temp.__dict__.update([object.__dict__])
NewClass = MixIn(Cat(), C, D)
test = NewClass()

__dict__, to my understanding, is suppose to be a dictionary, but
Python keeps telling me it's a 'dictproxy' object and that it has no
attribute 'update'. Why is this?

Thanks.
be************@lycos.com wrote:
I think it's possible, most of such kind of things are possible with
Python.
I'm not an expert yet in such kind of things, so this can be a starting
point for you (note the shadowing of m2, the class docstrings, etc).
Other people can give you something better or more correct.

class A:
def m1(self): return "m1"
def m2(self): return "m2"

class B:
def m3(self): return "m3"

class P:
def m2(self): return "m2b"
def m4(self): return"m4"

def mixin(object, *classes):
class NewClass(object.__class__):
pass
for C in classes:
NewClass.__dict__.update(C.__dict__)
object.__class__ = NewClass

foo = P()
print "Before:"
print "foo.__class__.__dict__.keys():", foo.__class__.__dict__.keys()
print "P.__dict__.keys():", P.__dict__.keys()
print "foo.m2():", foo.m2()
print "foo.m4():", foo.m4(), "\n"

mixin(foo, A, B)

print "After:"
print "foo.__class__.__dict__.keys():", foo.__class__.__dict__.keys()
print "P.__dict__.keys():", P.__dict__.keys()
print "foo.m1():", foo.m1()
print "foo.m2():", foo.m2()
print "foo.m3():", foo.m3()
print "foo.m4():", foo.m4()

Bye,
bearophile


Jun 25 '06 #4
di*************@gmail.com wrote:
(snip)
Two additional questions though: 1) is there a way for a function to
get a reference to its caller automatically (as in, without the caller
having to pass it in)?
It's possible with sys._getframe() and a decorator - but consider it a
hack.
and 2) what's the reason to use newstyle classes
versus the old?
All this is explained on python.org (there's a menu entry for this in
the documentation menu). AFAICT, newstyle classes can do whatever
oldstyle classes did, *and much more* (descriptors and usable
metaclasses) - and they are somewhat faster too. So - compatibility with
older Python versions (< 2.2 IIRC) set aside -, there's just no reason
to use oldstyle classes.
In order to create the dynamic class "NewClass" in the
code above I called type() but that requires at least one new style
class as a base. Thus, I had to have at least one of my animals inherit
from "object" and this seemed a nuisance since
OMG, eight more keystrokes - talk about a nuisance...
I don't at this point
know what the benefit of "newstyle" classes is.


See it the other way round : the *only* benefit of oldstyle classes is
compatibility with pre-2.2 Python versions.

--
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in 'o****@xiludom.gro'.split('@')])"
Jun 26 '06 #5
I can't give much answers, I am not that expert yet.

Bruno Desthuilliers:
newstyle classes can do whatever oldstyle classes
did, *and much more* (descriptors and usable
metaclasses) - and they are somewhat faster too.


In the past I have done few tests, and it seemed that new style classes
are a bit slower (but the difference doesn't make much difference).
Maybe for Py2.5 the situation will be different.

Bye,
bearophile

Jun 26 '06 #6

Bruno Desthuilliers wrote:
di*************@gmail.com wrote:
(snip)
Two additional questions though: 1) is there a way for a function to
get a reference to its caller automatically (as in, without the caller
having to pass it in)?
It's possible with sys._getframe() and a decorator - but consider it a
hack.


Gotcha, thanks.
and 2) what's the reason to use newstyle classes
versus the old?
All this is explained on python.org (there's a menu entry for this in
the documentation menu). AFAICT, newstyle classes can do whatever
oldstyle classes did, *and much more* (descriptors and usable
metaclasses) - and they are somewhat faster too. So - compatibility with
older Python versions (< 2.2 IIRC) set aside -, there's just no reason
to use oldstyle classes.
In order to create the dynamic class "NewClass" in the
code above I called type() but that requires at least one new style
class as a base. Thus, I had to have at least one of my animals inherit
from "object" and this seemed a nuisance since


OMG, eight more keystrokes - talk about a nuisance...


Like, Oh My God! *claps hand to mouth* lol You humor me. Yes, eight
more keystrokes. I follow the general rule of, if I'm going to put in
extra effort, I'd like to know why. So you see, it's not so much an
adversion to the eight keystrokes (multiplied by however many classes I
have mind you), but to not knowing why I should use them. If I don't
care for descriptors or metaclasses, I don't see why I should feel
compelled to use them. And when I decide I want/need these features, I
can put the eight keystroke in at that time. No biggy. :-) Thanks
Bruno.
I don't at this point
know what the benefit of "newstyle" classes is.


See it the other way round : the *only* benefit of oldstyle classes is
compatibility with pre-2.2 Python versions.

--
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in 'o****@xiludom.gro'.split('@')])"


Jun 26 '06 #7
di*************@gmail.com wrote:
Bruno Desthuilliers wrote:
di*************@gmail.com wrote: (snip)
and 2) what's the reason to use newstyle classes
versus the old?
All this is explained on python.org (there's a menu entry for this in
the documentation menu). AFAICT, newstyle classes can do whatever
oldstyle classes did, *and much more* (descriptors and usable
metaclasses) - and they are somewhat faster too. So - compatibility with
older Python versions (< 2.2 IIRC) set aside -, there's just no reason
to use oldstyle classes.

In order to create the dynamic class "NewClass" in the
code above I called type() but that requires at least one new style
class as a base. Thus, I had to have at least one of my animals inherit
from "object" and this seemed a nuisance since


OMG, eight more keystrokes - talk about a nuisance...

Like, Oh My God! *claps hand to mouth* lol You humor me. Yes, eight
more keystrokes. I follow the general rule of, if I'm going to put in
extra effort,


OMG, eight more keystrokes - talk about extra effort !-)
I'd like to know why.
The only reason for *not* doing it would be compat issues with pre 2.2.x
versions.
So you see, it's not so much an
adversion to the eight keystrokes (multiplied by however many classes I
have mind you),
Strange enough, I do write my share of Python code, and don't even
notice typing the EightKeystrokes.
but to not knowing why I should use them.
Because they are kind of the standard Python object model since 2.2.x ?-)

Did you at least take time to read the doc on newstyle classes on
python.org ?

FWIW, with 2.5, even exceptions are now newstyle classes. No more
oldstyle classes in the builtins. And AFAICT, no more oldstyle classes
in the standard lib neither. Does that ring a bell ?
If I don't
care for descriptors or metaclasses,
You *do* care for descriptors. Without descriptors, no properties, no
classmethods, no staticmethods... What a desolation :(

More seriously, given what you're into actually, not caring about what
one can do with newstyle classes seems really strange to me - like
digging a swimming-pool with a pick and a shovel when you have an
excavator... (disclaimer : google translation, not sure it makes sens in
english...)
I don't see why I should feel
compelled to use them.
"them" -> "newstyle classes" or "descriptors and metaclasses" ?
And when I decide I want/need these features, I
can put the eight keystroke in at that time.


What can I say ? That's your code, not mine...

--
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in 'o****@xiludom.gro'.split('@')])"
Jun 26 '06 #8

Bruno Desthuilliers wrote:
di*************@gmail.com wrote:
Bruno Desthuilliers wrote:
di*************@gmail.com wrote: (snip)
and 2) what's the reason to use newstyle classes
versus the old?

All this is explained on python.org (there's a menu entry for this in
the documentation menu). AFAICT, newstyle classes can do whatever
oldstyle classes did, *and much more* (descriptors and usable
metaclasses) - and they are somewhat faster too. So - compatibility with
older Python versions (< 2.2 IIRC) set aside -, there's just no reason
to use oldstyle classes.
In order to create the dynamic class "NewClass" in the
code above I called type() but that requires at least one new style
class as a base. Thus, I had to have at least one of my animals inherit
from "object" and this seemed a nuisance since

OMG, eight more keystrokes - talk about a nuisance...

Like, Oh My God! *claps hand to mouth* lol You humor me. Yes, eight
more keystrokes. I follow the general rule of, if I'm going to put in
extra effort,


OMG, eight more keystrokes - talk about extra effort !-)


As I said, its not the effort, its the personal need to know why the
effort, however small, is being put in.
I'd like to know why.
The only reason for *not* doing it would be compat issues with pre 2.2.x
versions.
So you see, it's not so much an
adversion to the eight keystrokes (multiplied by however many classes I
have mind you),


Strange enough, I do write my share of Python code, and don't even
notice typing the EightKeystrokes.
but to not knowing why I should use them.


Because they are kind of the standard Python object model since 2.2.x ?-)


What kind of answer is that? What does that actually mean to me? I'm
talking practical reasons here....

Did you at least take time to read the doc on newstyle classes on
python.org ?

FWIW, with 2.5, even exceptions are now newstyle classes. No more
oldstyle classes in the builtins. And AFAICT, no more oldstyle classes
in the standard lib neither. Does that ring a bell ?
Yes yes, but I've been able to use all that without declaring a single
new-style class. So my question was, what penalty do I actually pay...
If I don't
care for descriptors or metaclasses,


You *do* care for descriptors. Without descriptors, no properties, no
classmethods, no staticmethods... What a desolation :(

More seriously, given what you're into actually, not caring about what
one can do with newstyle classes seems really strange to me - like
digging a swimming-pool with a pick and a shovel when you have an
excavator... (disclaimer : google translation, not sure it makes sens in
english...)


You have it backwards. Of course I care what can be done with new-style
classes. That was precisely the basis for my original question. I
wanted to know what those eight keystrokes * #ofclasses gets me, and if
its necessary versus just a key to unlock features that I may or may
not need.

Jun 26 '06 #9

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
by: rbt | last post by:
What's the best way to take a string such as 'dog' and mix it up? You know, like the word jumble in the papers? ODG. I thought something like mix = random.shuffle('dog') would do it, but it won't....
5
by: Peter | last post by:
My client wants to develop a web application using Java. I have several questions and seeking for MVP advise. 1. Does IIS support Sun Micro Java? 2. Is it possible for .NET to mix with Java,...
10
by: sp0 | last post by:
Is there a reason why to make mix numbers improper when adding? It seems when subtracting and adding, adding a subtracting the whole numbers and fraction parts should be sufficient? what'ch think
5
by: AFN | last post by:
Hi. I'm pretty comfortable binding a single recordset result to a datagrid. But now I have a more unique problem. I have 2 really long stored procedures that cannot be combined at the SQL...
2
by: =?Utf-8?B?SmltIEN1dGxlcg==?= | last post by:
Does C# have problems when running a mix of release and debug builds of projects? I'm talking about something similar to the DLL hell you could get into with VC6 and the MFC shared library. If...
45
by: dolphin | last post by:
Is it a good thing that program mix C and C++?
1
by: rajraturi | last post by:
Dear I would like to know by applying which dll/API (.net/C#/vb) i can mix more than two audio file which would can mix on web based application.Some kind of dll as winmm.dll/Wavmix32.dll but...
5
by: Horacius ReX | last post by:
Hi, I have a C program split into different source files. I am trying a new compiler and for some reason it only accepts a single source file. So I need to "mix" all my different C source files...
1
by: JRough | last post by:
We got a dedicated hosted server to replace a shared hosted server. I reloaded the database tables and data and scripts. I noticed that most of the tables had latin1_swedish_collation but some...
1
by: metalmiketh | last post by:
I'm trying to make a table. within the table, one of the fields need to be a mix of integers, characters and special characters. how do i allow this?
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.