How to examine the inheritance of a class?

J

John Ladasky

Hello again!

Suppose that I have several subclasses which inherit from a base
class, thus:

class Foo(object):

class Spam1(Foo):

class Spam2(Foo):

class Spam3(Foo):

etc. The list of subclasses is not fully defined. It is supposed to
be extensible by the user.

Many methods will differ between these classes. However, there are
operations which may be performed between two Foo objects, OR between
any of Foo's derivatives.

There are instances where I would like to perform type checking before
carrying out the operation. Rather than having to enumerate all of
Foo's subclasses (which would defeat my intent of extending the list
of subclasses anyway), I would like to see whether a class is DERIVED
from Foo. Where is this information stored in the class definition?

Thanks!
 
J

John Ladasky

I forgot to add -- though I suspect it should not matter -- I'm using
Python 2.5.1 on Ubuntu Linux 8.04.
 
C

Chris Rebert

Hello again!

Suppose that I have several subclasses which inherit from a base
class, thus:

class Foo(object):

class Spam1(Foo):

class Spam2(Foo):

class Spam3(Foo):

etc. The list of subclasses is not fully defined. It is supposed to
be extensible by the user.

Many methods will differ between these classes. However, there are
operations which may be performed between two Foo objects, OR between
any of Foo's derivatives.

There are instances where I would like to perform type checking before
carrying out the operation. Rather than having to enumerate all of
Foo's subclasses (which would defeat my intent of extending the list
of subclasses anyway), I would like to see whether a class is DERIVED
from Foo. Where is this information stored in the class definition?

In __bases__, e.g. Spam1.__bases__, which would be (<class '__main__.Foo'>,).
In practice, you probably just want to use if isinstance(some_obj,
Foo): which will be true for SpamN instances.

Cheers,
Chris
 
J

James Mills

etc. The list of subclasses is not fully defined. It is supposed to
be extensible by the user.

Developer. NOT User.

Consider:

$ python
Python 2.5.2 (r252:60911, Oct 13 2008, 15:09:03)
[GCC 4.2.4 (CRUX)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
cheers
James
 
J

John Ladasky

In __bases__, e.g. Spam1.__bases__, which would be (<class '__main__.Foo'>,).
In practice, you probably just want to use if isinstance(some_obj,
Foo): which will be true for SpamN instances.


Thank you, Chris. Class.__bases__ is exactly what I wanted to see.
And I thought I had tried isinstance(), and found it lacking -- but I
just tried it again, and it does what I hoped it would do.
 
J

John Ladasky

Developer. NOT User.

For the foreseeable future, this program is for my use only. So the
developer and the user are one and the same.

And, thank you, __bases__ is what I was looking for. Though Chris
Mills also pointed out that isinstance() handles the type checking
nicely.
 
S

Steven D'Aprano

For the foreseeable future, this program is for my use only. So the
developer and the user are one and the same.

And, thank you, __bases__ is what I was looking for. Though Chris Mills
also pointed out that isinstance() handles the type checking nicely.

issubclass() may be better than directly looking at __bases__.

This may not matter if your only writing for yourself, but beware that
the use of issubclass() and isinstance() will wreck duck-typing and
prevent such things as delegation from working correctly.
 
D

Derek Martin

Developer. NOT User.

It's a semantic argument, but John's semantics are fine. A library is
code intended to be consumed by developers. The developers *are* the
users of the library. *End users* use applications, not libraries.

--
Derek D. Martin
http://www.pizzashack.org/
GPG Key ID: 0x81CFE75D


-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.1 (GNU/Linux)

iD8DBQFJAhOidjdlQoHP510RAjj6AKCBtlwV6J9s0oQ/KtP+WwlOdRsfsQCfdx95
LSCDarns+LTLbb4IAtgeCFs=
=BIaP
-----END PGP SIGNATURE-----
 
C

Craig Allen

Developer. NOT User.

I go around and around on this issue, and have ended up considering
anyone using my code a user, and if it's a library or class system,
likely that user is a programmer. I don't really think there is a
strong distinction... more and more users can do sophisticated
configuration which while not like what we do professionally as
software engineers... is not fundamentally different that programming,
making the distinction arbitrary.

I think the issue here for the term "user" is that there are many
kinds of user, many ways they can customize the system, and the
programmer/developer is just one kind of user. No?
 
C

Craig Allen

Thank you, Chris. Class.__bases__ is exactly what I wanted to see.
And I thought I had tried isinstance(), and found it lacking -- but I
just tried it again, and it does what I hoped it would do.

While isinstance is no doubt the proper way to access this
information, you may have run into problems because that isinstance
and ducktyping do not always work well together... because having a
particular interface does not mean you inherited that interface.
Checking __bases__ will not solve the problem either though, so best
to use isinstance if you can and document what you do well enough to
help people avoid breaking the assumptions of your system.

not that you didn't know that... but I thought it was worth saying
because I, at least, more and more do meta-class style techniques
which unfortunately do not play well with certain methods of checking
type.

-cba
 
F

Fuzzyman

It's a semantic argument, but John's semantics are fine.  A library is
code intended to be consumed by developers.  The developers *are* the
users of the library.  *End users* use applications, not libraries.


Except in the case of user scripting where end users of your
applications may well be using your APIs. :)

Michael Foord
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,743
Messages
2,569,478
Members
44,898
Latest member
BlairH7607

Latest Threads

Top