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

overriding method that returns base class object

I have a class A from a third party that I cannot change
and is implemented in C. I derive my own class B from A
and add a couple new methods and override a method. The
problem is that A has a method (call it A.f() ) that creates
and returns a new A object. I need B.f() to return a B
object derived from A.f(). What is the best way to make
that happen?

Jul 18 '05 #1
10 1658
Stuart McGraw wrote:

I have a class A from a third party that I cannot change
and is implemented in C. I derive my own class B from A
and add a couple new methods and override a method. The
problem is that A has a method (call it A.f() ) that creates
and returns a new A object. I need B.f() to return a B
object derived from A.f(). What is the best way to make
that happen?


If I understand this correctly, it has nothing to do with the
fact that the parent class is implemented in C and you just
need to know a little uncommon syntax:

class A:
def f(self):
return A()

class B(A):
def f(self):
obj = A.f(self)
# do whatever you want to obj here
return obj

The key is what you mean by "a B object derived from A.f()". If
by derived you mean something to do with _inheritance_, then
either you don't understand inheritance or you weren't clear what
you wanted.

If you just mean you want B's f() to do something special to the
A object that A.f() returns, then the above code should let you
do that properly...

-Peter
Jul 18 '05 #2
Sorry, you are right, I wasn't clear. I mean B inherits from
A. Here is what I am trying to do...

Class A has a method A.a() that returns an A. I want a
identical class but with an additional property .newprop
and method .b() And I want .a() to return a B, not an A.

class B (A):
def __init__(self, *args, **kwds):
A.__init__(self, *args, **kwds)
self.newprop = 99
def a(self):
x = A.a(self) # x is an A
x.__class__ = B
return x # I want x to be a B, i.e have b() and .newprop.
def b(self):
...something...

Yes, I know this is bogus. But I am not sure what
I should be doing. And to correct what I originally
posted, A is implented in python (but I still can't
change it for administrative reasons), but it's properties
are declared with "__slots__ = [...]" if that makes a
difference. This is all in Python 2.3.3.
"Peter Hansen" <pe***@engcorp.com> wrote in message news:40***************@engcorp.com...
Stuart McGraw wrote:

I have a class A from a third party that I cannot change
and is implemented in C. I derive my own class B from A
and add a couple new methods and override a method. The
problem is that A has a method (call it A.f() ) that creates
and returns a new A object. I need B.f() to return a B
object derived from A.f(). What is the best way to make
that happen?


If I understand this correctly, it has nothing to do with the
fact that the parent class is implemented in C and you just
need to know a little uncommon syntax:

class A:
def f(self):
return A()
se
class B(A):
def f(self):
obj = A.f(self)
# do whatever you want to obj here
return obj

The key is what you mean by "a B object derived from A.f()". If
by derived you mean something to do with _inheritance_, then
either you don't understand inheritance or you weren't clear what
you wanted.

If you just mean you want B's f() to do something special to the
A object that A.f() returns, then the above code should let you
do that properly...

-Peter

Jul 18 '05 #3
In article <40*********************@news.frii.net>,
Stuart McGraw <sm******@frii.RemoveThisToReply.com> wrote:

Class A has a method A.a() that returns an A. I want a
identical class but with an additional property .newprop
and method .b() And I want .a() to return a B, not an A.

class B (A):
def __init__(self, *args, **kwds):
A.__init__(self, *args, **kwds)
self.newprop = 99
def a(self):
x = A.a(self) # x is an A
x.__class__ = B
return x # I want x to be a B, i.e have b() and .newprop.
def b(self):
...something...

Yes, I know this is bogus. But I am not sure what I should be doing.
And to correct what I originally posted, A is implented in python
(but I still can't change it for administrative reasons), but it's
properties are declared with "__slots__ = [...]" if that makes a
difference. This is all in Python 2.3.3.


class A:
def a(self):
return self.__class__()
--
Aahz (aa**@pythoncraft.com) <*> http://www.pythoncraft.com/

"Argue for your limitations, and sure enough they're yours." --Richard Bach
Jul 18 '05 #4
Stuart McGraw wrote:
Sorry, you are right, I wasn't clear. I mean B inherits from
A. Here is what I am trying to do...

Class A has a method A.a() that returns an A. I want a
identical class but with an additional property .newprop
and method .b() And I want .a() to return a B, not an A.

class B (A):
def __init__(self, *args, **kwds):
A.__init__(self, *args, **kwds)
self.newprop = 99
def a(self):
x = A.a(self) # x is an A
x.__class__ = B
return x # I want x to be a B, i.e have b() and .newprop.
def b(self):
...something...

Yes, I know this is bogus. But I am not sure what
I should be doing.

Typically, you might want to do something like:

class B(A):
...
def a(self):
x = self.__class__.__new__(self.__class__,...)
# __new__ Usually gets no more args here, but

x.__init__(...)
# And here is where we do the actual init

...

Hope this helps

-Scott David Daniels
Sc***********@Acm.Org
Jul 18 '05 #5
"Aahz" <aa**@pythoncraft.com> wrote in message
news:c0**********@panix3.panix.com...
<snip>

class A:
def a(self):
return self.__class__()
--

OP can't do this, can't get at source code of A.

Assuming that you don't want to write __init__() to take an A argument, you
need something like:

class B(A):
def makeFromAnA(other): # other is an A instance
# construct a B - could pass initialization args from
# other if this is part of the interface
newB = B()

# ... copy base class A fields from other to newB here ...

# ... add B-ish stuff to newB here ...

return newB
makeFromAnA=staticmethod(makeFromAnA)

def a(self):
return B.makeFromAnA( A.a() )

Here's an example:
import random
class Point2D(object): # pretend this is implemented in C, so we can't
change the code
def __init__(self,xval,yval):
self.x = xval
self.y = yval
def randomPoint():
return Point2D( random.random()*100, random.random()*100 )
randomPoint=staticmethod(randomPoint)

class Point3D(Point2D): # not really good O-O design, but that's not the,
um, point
def __init__(self,xval,yval,zval):
self.x = xval
self.y = yval
self.z = zval
def make3DPtFrom2DPt(other):
print "Make 3D pt from",other
return Point3D(other.x,other.y,0)
# or if the __init__'s are not similar,
# manually assign fields
newPt3D = Point3D(0,0,0)
newPt3D.x = other.x
newPt3D.y = other.y
return newPt3D
make3DPtFrom2DPt=staticmethod(make3DPtFrom2DPt)
def randomPoint():
newPt = Point3D.make3DPtFrom2DPt( Point2D.randomPoint() )
newPt.z = random.random()*100
return newPt
randomPoint=staticmethod(randomPoint)

print Point2D.randomPoint()
print Point3D.randomPoint()

-- Paul
Jul 18 '05 #6

"Stuart McGraw" <sm******@frii.RemoveThisToReply.com> wrote in message
news:40*********************@news.frii.net...
Sorry, you are right, I wasn't clear. I mean B inherits from
A. Here is what I am trying to do...

Class A has a method A.a() that returns an A. I want a
identical class but with an additional property .newprop
and method .b() And I want .a() to return a B, not an A.

class B (A):
def __init__(self, *args, **kwds):
A.__init__(self, *args, **kwds)
self.newprop = 99
def a(self):
x = A.a(self) # x is an A
x.__class__ = B
return x # I want x to be a B, i.e have b() and .newprop.
def b(self):
...something...

Yes, I know this is bogus. But I am not sure what
I should be doing. And to correct what I originally
posted, A is implented in python (but I still can't
change it for administrative reasons), but it's properties
are declared with "__slots__ = [...]" if that makes a
difference. This is all in Python 2.3.3.
What's bogus about it? You can change the
class of an instance to be anything you want.
The only issue might be the slots; I'm not all
that familiar with what restrictions they might
impose.

Granted, there are relatively few cases
where changing the class of an instance on
the fly is actually better than the alternatives,
but this might be one of them.

John Roth


"Peter Hansen" <pe***@engcorp.com> wrote in message

news:40***************@engcorp.com...
Stuart McGraw wrote:

I have a class A from a third party that I cannot change
and is implemented in C. I derive my own class B from A
and add a couple new methods and override a method. The
problem is that A has a method (call it A.f() ) that creates
and returns a new A object. I need B.f() to return a B
object derived from A.f(). What is the best way to make
that happen?


If I understand this correctly, it has nothing to do with the
fact that the parent class is implemented in C and you just
need to know a little uncommon syntax:

class A:
def f(self):
return A()
se
class B(A):
def f(self):
obj = A.f(self)
# do whatever you want to obj here
return obj

The key is what you mean by "a B object derived from A.f()". If
by derived you mean something to do with _inheritance_, then
either you don't understand inheritance or you weren't clear what
you wanted.

If you just mean you want B's f() to do something special to the
A object that A.f() returns, then the above code should let you
do that properly...

-Peter

Jul 18 '05 #7
"Stuart McGraw" <sm******@frii.RemoveThisToReply.com> writes:
Class A has a method A.a() that returns an A. I want a
identical class but with an additional property .newprop
and method .b() And I want .a() to return a B, not an A.

class B (A):
def __init__(self, *args, **kwds):
A.__init__(self, *args, **kwds)
self.newprop = 99
def a(self):
x = A.a(self) # x is an A
x.__class__ = B
return x # I want x to be a B, i.e have b() and .newprop.
Ugh!!
Yes, I know this is bogus. But I am not sure what I should be doing.


I think you have to make B into a container for an A. Something like:

class B(A):
def __init__(self, *args, **kwds):
self.newprop = 99
self.wrapped_A = A(*args, **kwds)
def a(self):
x = B()
x.wrapped_A = A.a(self.wrapped_A)
return # I want x to be a B, i.e have b() and .newprop.
def __getattr__(self, attr):
# delegate all inherited operations to the wrapped A object
return A.__getattr__(self.wrapped_A, attr)

You might also be able to do something crazy, like change A's metaclass
so that its __new__ operation can make a B under certain circumstances.
Jul 18 '05 #8

"Scott David Daniels" <Sc***********@Acm.Org> wrote in message news:40********@nntp0.pdx.net...
Stuart McGraw wrote:
Sorry, you are right, I wasn't clear. I mean B inherits from
A. Here is what I am trying to do...

Class A has a method A.a() that returns an A. I want a
identical class but with an additional property .newprop
and method .b() And I want .a() to return a B, not an A.

class B (A):
def __init__(self, *args, **kwds):
A.__init__(self, *args, **kwds)
self.newprop = 99
def a(self):
x = A.a(self) # x is an A
x.__class__ = B
return x # I want x to be a B, i.e have b() and .newprop.
def b(self):
...something...

Yes, I know this is bogus. But I am not sure what
I should be doing.

Typically, you might want to do something like:

class B(A):
...
def a(self):
x = self.__class__.__new__(self.__class__,...)
# __new__ Usually gets no more args here, but

x.__init__(...)
# And here is where we do the actual init


I don't think this will work. A.a() returns an A, but one that
is initialized differently than an A() instance. That is, A.a()
does more that just __new__() and __init__() to it. So if I
do the above, I end up with a subtype (right word?) of an
A(), not an A.a().

Now I think that my B.a() must call A.a() and somehow
dynamically change the type of the object received? As suggesed
above, I tried to change the class (x.__class__ = B) but that
just results in an exception
TypeError: __class__ assignment: 'B' object layout differs from 'A'

Or maybe what I am trying to do is not possible in Python?

Jul 18 '05 #9
"Paul Rubin" <http://ph****@NOSPAM.invalid> rote in message news:7x************@ruckus.brouhaha.com...
"Stuart McGraw" <sm******@frii.RemoveThisToReply.com> writes:
Class A has a method A.a() that returns an A. I want a
identical class but with an additional property .newprop
and method .b() And I want .a() to return a B, not an A.

class B (A):
def __init__(self, *args, **kwds):
A.__init__(self, *args, **kwds)
self.newprop = 99
def a(self):
x = A.a(self) # x is an A
x.__class__ = B
return x # I want x to be a B, i.e have b() and .newprop.


Ugh!!
Yes, I know this is bogus. But I am not sure what I should be doing.


I think you have to make B into a container for an A. Something like:

class B(A):
def __init__(self, *args, **kwds):
self.newprop = 99
self.wrapped_A = A(*args, **kwds)
def a(self):
x = B()
x.wrapped_A = A.a(self.wrapped_A)
return # I want x to be a B, i.e have b() and .newprop.
def __getattr__(self, attr):
# delegate all inherited operations to the wrapped A object
return A.__getattr__(self.wrapped_A, attr)

You might also be able to do something crazy, like change A's metaclass
so that its __new__ operation can make a B under certain circumstances.


Ahhhh.... I did not know about delegation. I do now, thanks.
A minor disadvantage is that, because I also delegate __setattr__
all the instance variable have to be assigned in the form
self.__dict__['var'], rather than self.var (as I discovered the hard
way). Ugly, but I can live with it. Thanks again.
Jul 18 '05 #10
Stuart McGraw wrote:
"Paul Rubin" <http://ph****@NOSPAM.invalid> rote in message news:7x************@ruckus.brouhaha.com...
...
class B(A):
def __init__(self, *args, **kwds):
self.newprop = 99
self.wrapped_A = A(*args, **kwds)
def a(self):
x = B()
x.wrapped_A = A.a(self.wrapped_A)
return # I want x to be a B, i.e have b() and .newprop.
def __getattr__(self, attr):
# delegate all inherited operations to the wrapped A object
return A.__getattr__(self.wrapped_A, attr)

You might also be able to do something crazy, like change A's metaclass
so that its __new__ operation can make a B under certain circumstances.


Ahhhh.... I did not know about delegation. I do now, thanks.
A minor disadvantage is that, because I also delegate __setattr__
all the instance variable have to be assigned in the form
self.__dict__['var'], rather than self.var (as I discovered the hard
way). Ugly, but I can live with it. Thanks again.


If you can separate the names, you can do something like:

class B(object):
def __init__(self, *args, **kwargs):
self._a = A(*args, **kwargs)
self.newprop = 99
def __setattr__(self, name, val):
if name.startswith('_') or name == 'newprop':
self.__dict__[name] = val
else:
setattr(self._a, name, val)
def getattr(self, name):
return getattr(self._a, name)

--
-Scott David Daniels
Sc***********@Acm.Org
Jul 18 '05 #11

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

Similar topics

2
by: Ovid | last post by:
Hi, I'm trying to determine the cleanest way to override class data in a subclass. class Universe { public String name; private static double PI = 3.1415; Universe(String name) {
3
by: Ali Eghtebas | last post by:
Hi, I have 3 questions regarding the code below: 1) Why can't I trap the KEYDOWN while I can trap KEYUP? 2) Is it correct that I use Return True within the IF-Statement? (I've already read...
4
by: Rafael Veronezi | last post by:
I have some questions about override in inheritance, and virtual members. I know that you can you override a method by two ways in C#, one, is overriding with the new keyword, like: public new...
12
by: Rubbrecht Philippe | last post by:
Hi there, According to documentation I read the ArrayList.IndexOf method uses the Object.Equals method to loop through the items in its list and locate the first index of an item that returns...
18
by: JohnR | last post by:
From reading the documentation, this should be a relatively easy thing. I have an arraylist of custom class instances which I want to search with an"indexof" where I'm passing an instance if the...
3
by: David Scarlett | last post by:
Hi all, I've got a question regarding overriding const member functions with non-const functions. Let's say I've got a base class defined as follows: /*******************/ class Foo {...
8
by: Kenneth Baltrinic | last post by:
When one overrides the Equals() method of an object, one is supposed to override GetHashCode() as well and this makes good sense. But I have seen lots of people who do this and do not override the...
6
by: bryanbabula | last post by:
I have a question about overriding i was wondering if anyone could help me with, or even suggesting a better/different way. I have no idea if this can even be done or not. I was wondering if there...
10
by: r035198x | last post by:
The Object class has five non final methods namely equals, hashCode, toString, clone, and finalize. These were designed to be overridden according to specific general contracts. Other classes that...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
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?
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...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
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
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...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 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 a new...

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.