473,379 Members | 1,377 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,379 software developers and data experts.

converting base class instance to derived class instance

Consider the code below,

class Base(object):
pass

class Derived(object):

def __new__(cls, *args, **kwds):
# some_factory returns an instance of Base
# and I have to derive from this instance!
inst = some_factory() # this returns instance of Base
return inst # Oops! this isn't an instance of Derived

def __init__(self):
# This won't be called as __new__ returns Base's instance
pass

The constrait is there is some factory function that creates an
instance of Base class. So I _can't_ call "Base.__init__(self)" in
Derived.__init__ func, as their will be _two_ instances (one created
by Derived.__init__ and other created by the factory function)

Simply I want to get a derived class object, but instead of allowing
_automatic_ creation of Base instance, I want to use _existing_ Base's
instance, then use this as a Derived's instance.

Will metaclass solve this problem?
Jul 18 '05 #1
14 3290
Sridhar R wrote:
Consider the code below,

class Base(object):
pass

class Derived(object):
I suppose that should be

class Derived(Base):
def __new__(cls, *args, **kwds):
# some_factory returns an instance of Base
# and I have to derive from this instance!
inst = some_factory() # this returns instance of Base
# using brute force:
inst.__class__ = Derived

No guarantees, but the above seems to work.
return inst # Oops! this isn't an instance of Derived

def __init__(self):
# This won't be called as __new__ returns Base's instance
pass

The constrait is there is some factory function that creates an
instance of Base class. So I _can't_ call "Base.__init__(self)" in
Derived.__init__ func, as their will be _two_ instances (one created
by Derived.__init__ and other created by the factory function)
As some_factory() returns an already initialized instance of Base, there
should be no need to call it again from inside Derived.__init__()
Simply I want to get a derived class object, but instead of allowing
_automatic_ creation of Base instance, I want to use _existing_ Base's
instance, then use this as a Derived's instance.

Will metaclass solve this problem?


I think metaclasses will solve only metaproblems...

Skeptically yours,
Peter

Jul 18 '05 #2

"Sridhar R" <sr*************@yahoo.com> wrote in message
news:93**************************@posting.google.c om...
Consider the code below,

class Base(object):
pass

class Derived(object):

def __new__(cls, *args, **kwds):
# some_factory returns an instance of Base
# and I have to derive from this instance!
inst = some_factory() # this returns instance of Base
return inst # Oops! this isn't an instance of Derived

def __init__(self):
# This won't be called as __new__ returns Base's instance
pass
__new__ can return an instance of any class it pleases.
It's not restricted to returning an instance of the class it
happens to be in, nor is it restricted to returning a newly
created instance, for that matter. It can do the entire
construction job without using the __init__ method.

However, I don't think that's the best solution. If
your factory is going to return instances of several
different classes, I think it's best that it be an explicit
factory method or function, not something that magically
happens in a class constructor. I'd rather not have to
deal with programs where class constructors pass me
instances of classes other than the one I'm calling.

If you want to do a little bit of deep magic, a factory
function can create an instance by calling object(),
plug in whatever attributes it wants and then change the
__class__ attribute to whatever class it wants before
it returns the newly minted instance. It doesn't have to
go near anything that resembles a constructor (other than
calling object() to get a new instance, of course.)
The constraint is there is some factory function that creates an
instance of Base class. So I _can't_ call "Base.__init__(self)" in
Derived.__init__ func, as their will be _two_ instances (one created
by Derived.__init__ and other created by the factory function)

Simply I want to get a derived class object, but instead of allowing
_automatic_ creation of Base instance, I want to use _existing_ Base's
instance, then use this as a Derived's instance.

Will metaclass solve this problem?


Wrong tool. Metaclasses are used to set up classes, not to
set up instances.

John Roth
Jul 18 '05 #3
sr*************@yahoo.com (Sridhar R) wrote in message news:<93**************************@posting.google. com>...
Consider the code below,

class Base(object):
pass

class Derived(object):

def __new__(cls, *args, **kwds):
# some_factory returns an instance of Base
# and I have to derive from this instance!
inst = some_factory() # this returns instance of Base
return inst # Oops! this isn't an instance of Derived

def __init__(self):
# This won't be called as __new__ returns Base's instance
pass

The constrait is there is some factory function that creates an
instance of Base class. So I _can't_ call "Base.__init__(self)" in
Derived.__init__ func, as their will be _two_ instances (one created
by Derived.__init__ and other created by the factory function)

Simply I want to get a derived class object, but instead of allowing
_automatic_ creation of Base instance, I want to use _existing_ Base's
instance, then use this as a Derived's instance.

Will metaclass solve this problem?


I don't really understand what you want to do (i.e. do you want
Derived.__init__ to be called or not?). Moreover, as others pointed
out, it is cleaner to use a class factory than to pervert __new__.
If you really want to use a metaclass, you could override the
__call__ method of the metaclass, in such a way to interfer with the
class instantiation. For instance, this is the code to make a singleton
class (which is a FAQ ;)

class Singleton(type):
"Instances of this metaclass are singletons"
def __init__(cls,name,bases,dic):
super(Singleton,cls).__init__(name,bases,dic)
cls.instance=None
def __call__(cls,*args,**kw):
if cls.instance is None:
cls.instance=super(Singleton,cls).__call__(*args,* *kw)
return cls.instance

class C:
__metaclass__=Singleton

This is not what you want but you can play with __call__ and get
the behavior you want. Still, why don't just use a simple factory?

Michele Simionato
Jul 18 '05 #4
[John Roth]
If you want to do a little bit of deep magic, a factory function can
create an instance by calling object(), plug in whatever attributes
it wants and then change the __class__ attribute to whatever class it
wants before it returns the newly minted instance. It doesn't have
to go near anything that resembles a constructor (other than calling
object() to get a new instance, of course.)


Hello, John, and gang! :-)

How one does that? I'm merely curious. Using Python 2.3.3, the result
of `object()' does not have a `__dict__', and seemingly may not be given
a `__dict__' either. See:
Python 2.3.3 (#1, Jan 24 2004, 09:01:30)
[GCC 3.3 20030226 (prerelease) (SuSE Linux)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
from __future__ import division
from __future__ import division
o = object()
o.__dict__ Traceback (most recent call last):
File "<stdin>", line 1, in ?
AttributeError: 'object' object has no attribute '__dict__' o.__dict__ = {} Traceback (most recent call last):
File "<stdin>", line 1, in ?
AttributeError: 'object' object has no attribute '__dict__' class C(object): pass .... o.__class__ = C Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: __class__ assignment: only for heap types

By the way, what is a "heap type"?

--
François Pinard http://www.iro.umontreal.ca/~pinard

Jul 18 '05 #5

"François Pinard" <pi****@iro.umontreal.ca> wrote in message
news:ma***************************************@pyt hon.org...
[John Roth]
If you want to do a little bit of deep magic, a factory function can
create an instance by calling object(), plug in whatever attributes
it wants and then change the __class__ attribute to whatever class it
wants before it returns the newly minted instance. It doesn't have
to go near anything that resembles a constructor (other than calling
object() to get a new instance, of course.)


Hello, John, and gang! :-)

How one does that? I'm merely curious. Using Python 2.3.3, the result
of `object()' does not have a `__dict__', and seemingly may not be given
a `__dict__' either. See:

[John's answer]
My goof. The correct call is:

object.__new__(klas)

where klas is the class object you want
the instance constructed for.
John Roth
--
François Pinard http://www.iro.umontreal.ca/~pinard
Jul 18 '05 #6
Fran�ois Pinard wrote:
By the way, what is a "heap type"?


I don't know, but:

http://foldoc.doc.ic.ac.uk/foldoc/fo...&action=Search

heap

1. <programming> An area of memory used for dynamic memory allocation
where blocks of memory are allocated and freed in an arbitrary order and
the pattern of allocation and size of blocks is not known until run
time. Typically, a program has one heap which it may use for several
different purposes.

Heap is required by languages in which functions can return arbitrary
data structures or functions with free variables (see closure). In C
functions malloc and free provide access to the heap.

Contrast stack. See also dangling pointer.

2. <programming> A data structure with its elements partially ordered
(sorted) such that finding either the minimum or the maximum (but not
both) of the elements is computationally inexpensive (independent of the
number of elements), while both adding a new item and finding each
subsequent smallest/largest element can be done in O(log n) time, where
n is the number of elements.

Formally, a heap is a binary tree with a key in each node, such that all
the leaves of the tree are on two adjacent levels; all leaves on the
lowest level occur to the left and all levels, except possibly the
lowest, are filled; and the key in the root is at least as large as the
keys in its children (if any), and the left and right subtrees (if they
exist) are again heaps.

Note that the last condition assumes that the goal is finding the
minimum quickly.

Heaps are often implemented as one-dimensional arrays. Still assuming
that the goal is finding the minimum quickly the invariant is

heap[i] <= heap[2*i] and heap[i] <= heap[2*i+1] for all i,
where heap[i] denotes the i-th element, heap[1] being the first.
Heaps can be used to implement priority queues or in sort algorithms.
And:

http://www.python.org/dev/doc/devel/...ule-heapq.html
Heaps are arrays for which heap[k] <= heap[2*k+1] and heap[k] <=
heap[2*k+2] for all k, counting elements from zero. For the sake of
comparison, non-existing elements are considered to be infinite. The
interesting property of a heap is that heap[0] is always its smallest
element.

Gerrit.

--
PrePEP: Builtin path type
http://people.nl.linux.org/~gerrit/c.../pep-xxxx.html
Asperger's Syndrome - a personal approach:
http://people.nl.linux.org/~gerrit/english/

Jul 18 '05 #7
[John Roth]
If you want to do a little bit of deep magic, a factory function can
create an instance by calling object(), [...] My goof. The correct
call is: object.__new__(klas) [...]


OK, thanks. `object.__new__' is what I was using already. It was
looking kosher to me because of the explanations in `descrintro'. Maybe
I was seduced and tempted by the announced bit of deep magic, and was
trying to rediscover the secret. My little Harry Potter side! :-)

--
François Pinard http://www.iro.umontreal.ca/~pinard

Jul 18 '05 #8
[Gerrit]
[François Pinard]
By the way, what is a "heap type"?
http://foldoc.doc.ic.ac.uk heap [...] 1. An area of memory [...]
2. A data structure [...]
Wow, Gerrit, I appreciate your effort in providing this comprehensive
answer (and am saving the reference to `foldoc', which looks useful).
My question was likely ambiguous, sorry. Reading "heap type" in an
article written in the context of Python new-style classes, I wondered
if "heap type" did not refer to some classification of Python types
which I did not know, but should know.
http://www.python.org/dev/doc/devel/...ule-heapq.html


If you follow the `Theory' link from the page above, you might see that
I wrote this explanation. The editor was kind above to push my name in
there :-). Not really that I expected it, it even surprised me. On the
other hand, it officialises a tiny bit the fact that I much like Python!

--
François Pinard http://www.iro.umontreal.ca/~pinard

Jul 18 '05 #9

"François Pinard" <pi****@iro.umontreal.ca> wrote in message
news:ma***************************************@pyt hon.org...
o.__class__ = C Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: __class__ assignment: only for heap types
By the way, what is a "heap type"?
I think they're refering to objects that are allocated
on the heap. I'm not sure what attempting to
instantiate object would do, but I suspect the result
would be a built-in that can't be modified.

John Roth

--
François Pinard http://www.iro.umontreal.ca/~pinard
Jul 18 '05 #10
[John Roth]
[François Pinard]
>> o.__class__ = C

Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: __class__ assignment: only for heap types

By the way, what is a "heap type"?

I think they're refering to objects that are allocated on the
heap. I'm not sure what attempting to instantiate object would do, but
I suspect the result would be a built-in that can't be modified.


Someone suggested, on this list, that `object()' could be used for
cheaply producing an object which is guaranteed unique, when there is no
need for that object to have any other property.

If you do:

a = object()
b = object()
c = object()
...

you will observe that they are all different, none of `a', `b', `c'
compare with `is' to another. I do not see how the result could be
built-in or pre-allocated.

I could understand that some immutable objects, like 0, "z" or () could
be allocated statically. But for `object()', I do not see.

--
François Pinard http://www.iro.umontreal.ca/~pinard

Jul 18 '05 #11
François Pinard <pi****@iro.umontreal.ca> wrote in message news:<ma***************************************@py thon.org>...
By the way, what is a "heap type"?


More or less, an user defined type, as opposed to a builtin type:

http://groups.google.it/groups?hl=it....lang.python.*
Jul 18 '05 #12

"François Pinard" <pi****@iro.umontreal.ca> wrote in message
news:ma***************************************@pyt hon.org...
[John Roth]
[François Pinard]
>> o.__class__ = C

Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: __class__ assignment: only for heap types

By the way, what is a "heap type"?

I think they're refering to objects that are allocated on the
heap. I'm not sure what attempting to instantiate object would do, but
I suspect the result would be a built-in that can't be modified.


Someone suggested, on this list, that `object()' could be used for
cheaply producing an object which is guaranteed unique, when there is no
need for that object to have any other property.

If you do:

a = object()
b = object()
c = object()
...

you will observe that they are all different, none of `a', `b', `c'
compare with `is' to another. I do not see how the result could be
built-in or pre-allocated.

I could understand that some immutable objects, like 0, "z" or () could
be allocated statically. But for `object()', I do not see.

[John Roth]
But I believe that object itself is a built-in type, and the error
message in question specified "heap TYPE".

John Roth

--
François Pinard http://www.iro.umontreal.ca/~pinard
Jul 18 '05 #13
[Michele Simionato]
François Pinard <pi****@iro.umontreal.ca> wrote in message news:<ma***************************************@py thon.org>...
By the way, what is a "heap type"?
More or less, an user defined type, as opposed to a builtin type: http://groups.google.it/groups?hl=it....lang.python.*


That sequence of articles was instructive, thanks!

Maybe the Python documentation should be amended, somewhere, somehow, so
the expression "heap type" is explained. Or maybe it is already and I
just did not find it. The fact is that it is used in a diagnostic.

--
François Pinard http://www.iro.umontreal.ca/~pinard

Jul 18 '05 #14
[John Roth]
But I believe that object itself is a built-in type, and the error
message in question specified "heap TYPE".


I understand what you say, and it sounds logical. Thanks!

--
François Pinard http://www.iro.umontreal.ca/~pinard

Jul 18 '05 #15

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

Similar topics

2
by: Gabriel Genellina | last post by:
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...
9
by: Banaticus Bart | last post by:
I wrote an abstract base class from which I've derived a few other classes. I'd like to create a base class array where each element is an instance of a derived object. I can create a base class...
3
by: J.J. Feminella | last post by:
(Please disregard the previous message; I accidentally sent it before it was completed.) I have source code similar to the following. public class Vehicle { protected string dataV; // ......
6
by: Microsoft | last post by:
Base class: class AssetBase { string _clli; public string CLLI { get
7
by: Baski | last post by:
Base class: class AssetBase { string _clli; public string CLLI { get
24
by: AtariPete | last post by:
Hey All, I have a C# question for you regarding up casting (base to derived). I was wondering about the most elegant way (readable, less code) to cast from a base type to its derived type....
26
by: nyathancha | last post by:
Hi, How Do I create an instance of a derived class from an instance of a base class, essentially wrapping up an existing base class with some additional functionality. The reason I need this is...
15
by: =?Utf-8?B?R2Vvcmdl?= | last post by:
Hello everyone, I met with a strange issue that derived class function can not access base class's protected member. Do you know why? Here is the error message and code. error C2248:...
13
by: Rahul | last post by:
Hi Everyone, I was just playing around virtual functions and landed up with the following, class Base1 { public: virtual void sample() { printf("base::sample\n");
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
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: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
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: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
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...

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.