473,221 Members | 2,076 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,221 software developers and data experts.

mixin class

Hi,

I try to implement mixin classes. Thats why I
need to make a new class at runtime.

--tmp.py-------------------------------------

import new

class K1(object):
pass

class K2(object):
pass

mixed = new.classobj("K1_K2", (K1, K1), {})
new_instance = new.instance(mixed, {})

print new_instance

---------------------------------------------

Making a new instance from the new class works
only if K1 is not derived from object. If I use
new style classes I get the following traceback:

Traceback (most recent call last):
File "tmp.py", line 10, in ?
new_instance = new.instance(mixed, {})
TypeError: instance() argument 1 must be class, not type

I use Python 2.2.3 and Win2000.

My question: How do I implement mixin classes
with new style classes?

Thanks,

Udo

Jul 18 '05 #1
5 2710
Udo Gleich <ud********@web.de> wrote in message news:<3F***************@web.de>...
Hi,

I try to implement mixin classes. Thats why I
need to make a new class at runtime.

--tmp.py-------------------------------------

import new

class K1(object):
pass

class K2(object):
pass

mixed = new.classobj("K1_K2", (K1, K1), {})
new_instance = new.instance(mixed, {})

print new_instance

---------------------------------------------

Making a new instance from the new class works
only if K1 is not derived from object. If I use
new style classes I get the following traceback:

Traceback (most recent call last):
File "tmp.py", line 10, in ?
new_instance = new.instance(mixed, {})
TypeError: instance() argument 1 must be class, not type

I use Python 2.2.3 and Win2000.

My question: How do I implement mixin classes
with new style classes?

Thanks,

Udo


Why not simply

class K1(object):
pass

class K2(object):
pass

mixed = type("K1_K2", (K1, K1), {})
new_instance = mixed()

print new_instance

?

"type" is described in http://www.python.org/2.2.3/descrintro.html
(in one line very easy to miss ;)
Michele
Jul 18 '05 #2
Hi,
Why not simply

class K1(object):
pass

class K2(object):
pass

mixed = type("K1_K2", (K1, K1), {})
new_instance = mixed()

print new_instance


almost.

If K1 has a constructor that takes arguments you get an
error when you call the constructor of the derived class
without an argument. Why do I want to do that? Usually
one would say that I should know the arguments of the
constructor of the derived class.

What I want to do is take *two objects*, derive from both
their classes, make a new object and combine the state of
the old objects.

I dont know if that is a good idea. I would appreciate comments
on the following solution. Especially the use of the dummy_init
function as an empty constructor looks not quite right to me.

---------------------------------------------------------------------

def dummy_init(self):
pass

class Mixin:

__shared_state = {"classes":{}}

def __init__(self):
self.__dict__ = self.__shared_state

def mix(self, original_instance, mixin_instance):
original_class = original_instance.__class__
mixin_class = mixin_instance.__class__
name = original_class.__name__ + '_' + mixin_class.__name__
mixed = self.classes.get(name,
type(name,
(mixin_class, original_class),
{"__init__": dummy_init}))
new_instance = mixed()

new_instance.__dict__.update(mixin_instance.__dict __)
new_instance.__dict__.update(original_instance.__d ict__)

try:
new_instance.late_init_original()
except AttributeError:
pass
try:
new_instance.late_init_mixin()
except AttributeError:
pass
return new_instance

class K1(object):
def __init__(self, a):
self.a = a

class K2(object):
def late_init_mixin(self):
self.b = self.a + 1
mixer = Mixin()

new_instance = mixer.mix(K1(3), K2())

print new_instance
print new_instance.a, new_instance.b

-------------------------------------------------------------------------
Jul 18 '05 #3
> > mixed = new.classobj("K1_K2", (K1, K1), {})

There is an error in the code. Obviously it should
read

mixed = new.classobj("K1_K2", (K1, K2), {})
--
Jul 18 '05 #4
Udo Gleich <ud********@web.de> wrote in message news:<3F***************@web.de>...
What I want to do is take *two objects*, derive from both
their classes, make a new object and combine the state of
the old objects.

I dont know if that is a good idea. I would appreciate comments
on the following solution. Especially the use of the dummy_init
function as an empty constructor looks not quite right to me.


You may avoid dummy_init and have the default object.__init__ but
this is not the point. The whole construction seems ugly to me.
Do you have the option of using only class variables ? I mean, no
explicit instance dictionary? Then you could simply create the
mixin from the original classes and not merge by hand the
instance dictionaries. Do you have the option of modifying the
original classes to make the all structure more multiple inheritance
friendly? The idea is that one should derive objects from classes,
not classes from objects. What you are doing will probably work,
but It is quite ugly to me.I cannot say more if I have no idea of what
are your constraints. If you cannot touch the original classes,
remember that you can create modifications of them, as mixin-frendly
as you wish. I also have a question: why don't you override the
__init__ method in M in such a way that it calls K1.__init__ and
K2.__init__ according to the number of arguments? That would be
the first thing would come to my mind, but maybe you have reasons
why you don't want that.
HTH,
Michele
Jul 18 '05 #5
On Mon, 28 Jul 2003 12:20:02 +0200, Udo Gleich wrote:
My question: How do I implement mixin classes
with new style classes?


Um, if I understand what you're trying to do correctly, it's easy:

--------------
import random

class A(object): pass
class B(object): pass
class C(object): pass
class D(object): pass

mixin = random.choice([C, D])

class A_B_and_C_or_D(A, B, mixin): pass

newName = A_B_and_C_or_D

newInstance = newName()
----------------

(Warning: Didn't actually type this in)

The classes being derived from can be variable; in fact I do this rather
too frequently for my own good, perhaps. (I tend to use it for class I
want to be intimately involved with each other, but also usable
separately, having one of them dynamically derive from either object or
the other class, depending on whether the other class is available.)

So in this example, on any given run, class A_B_and_C_or_D will always
derive from A and B, and may derive from either of C or D.

You can dynamically do this in a loop or something if you're feeling
creative, if you assign the class to new names, as I did here for
"newName". AFAIK there's no way to programmatically create new classes
with generated names without resorting to eval (bad idea), but you can
bind them to new names after creation and that works OK.

----------------

classesILike = {}
for i in range(10):
class tmp(object): pass
classesILIke[i] = tmp

----------------

and of course "tmp" may derive from what it will.

The inheritance list is as dynamic as anything else in Python; feel free
to use it that way. Personally I find this is a "killer feature"... you'd
find it hard to describe in advance when you'd want it, but when
you want it, you want it ***badly***, because the kludge will be a
killer... and there are very, very few languages that can do this cleanly
(and still share Python's other benefits).
Jul 18 '05 #6

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

Similar topics

0
by: zimba | last post by:
Hello ! If somebody is interested, here is a small hack I've done today. There are still some curious effects, but I'm pretty satisfied by the results, since PHP is not very flexible. Let...
1
by: Mac | last post by:
I have a MixIn class which defines a method foo(), and is then mixed in with another class by being prepended to that class's __bases__ member, thus overriding that class's definition of foo(). In...
0
by: Paolino | last post by:
I had always been negative on the boldeness of python on insisting that unbound methods should have been applied only to its im_class instances. Anyway this time I mixed in rightly, so I post this...
0
by: barnesc | last post by:
>So mixins are just a sub-class of sub-classing? > >I've just found this: > > >A mixin class is a parent class that is inherited from - but not as >a means of specialization. Typically, the...
6
by: Alex Hunsley | last post by:
I know that I can catch access to unknown attributes with code something like the following: class example: def __getattr__(self, name): if name == 'age': return __age else: raise...
3
by: Ed Leafe | last post by:
In Dabo, we create cursor classes that combine the backend-specific dbapi cursor class with our own mixin class that adds framework- specific behaviors. This has been working well for a couple of...
2
by: ish | last post by:
I think this is more of a style question than anything else... I'm doing a C++ wrapper around a C event library I have and one of the items is a timer class, I'm also using this task to learn C++....
1
by: Ole Nielsby | last post by:
Given these 3 classes class A {virtual void a(){}}; class B {virtual void b(){}}; class C: public A, public B {}; I want the offset of B in C, as a size_t value, and preferably as a constant...
2
by: viboes | last post by:
Hello, Very often we need to name the basetype of a derived type class D : public B { typedef B base_type; // ... }; When B es a complexe template expression we need to repeat the
0
by: veera ravala | last post by:
ServiceNow is a powerful cloud-based platform that offers a wide range of services to help organizations manage their workflows, operations, and IT services more efficiently. At its core, ServiceNow...
0
by: VivesProcSPL | last post by:
Obviously, one of the original purposes of SQL is to make data query processing easy. The language uses many English-like terms and syntax in an effort to make it easy to learn, particularly for...
3
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 3 Jan 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). For other local times, please check World Time Buddy In...
0
by: mar23 | last post by:
Here's the situation. I have a form called frmDiceInventory with subform called subfrmDice. The subform's control source is linked to a query called qryDiceInventory. I've been trying to pick up the...
0
by: abbasky | last post by:
### Vandf component communication method one: data sharing ​ Vandf components can achieve data exchange through data sharing, state sharing, events, and other methods. Vandf's data exchange method...
2
by: jimatqsi | last post by:
The boss wants the word "CONFIDENTIAL" overlaying certain reports. He wants it large, slanted across the page, on every page, very light gray, outlined letters, not block letters. I thought Word Art...
2
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 7 Feb 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:30 (7.30PM). In this month's session, the creator of the excellent VBE...
0
by: stefan129 | last post by:
Hey forum members, I'm exploring options for SSL certificates for multiple domains. Has anyone had experience with multi-domain SSL certificates? Any recommendations on reliable providers or specific...
1
by: davi5007 | last post by:
Hi, Basically, I am trying to automate a field named TraceabilityNo into a web page from an access form. I've got the serial held in the variable strSearchString. How can I get this into the...

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.