derived / base class name conflicts

  • Thread starter christopherlmarshall
  • Start date
C

christopherlmarshall

Suppose you want to write a subclass of some existing class you are
importing from a module you didn't write and that you don't want to
study the internals of, and you want to define a data member i in your
constructor.

As in the following:

from module1 import A

class B(A):
def __init__(self):
A.__init__(self)
self.i= 0
b= B()

Now, 'i' might have already been defined by A or by the call to
A.__init__() so if you define it without knowing that, you could be
changing the behavior of A's methods in unknown ways, which is
obviously a bad thing.

One way to avoid this is to run the following program to clear the name
'i' first:

from module1 import A
a= A()
print a.i

If you get an AttributeError, you know the name 'i' is safe to use. If
you actually get some sort of report from the print statement, then you
will know that 'i' is not safe to use.

This strikes me as a rather odd procedure to go through, but I don't
see any way around it.

It there some other way to handle this issue?

Do I actually need to study the sources for / implementation of
Tkinter.Canvas before I can safely subclass it (and assign attributes
to an instance of the subclass) or clear attribute names as I outlined
above?

Chris Marshall
 
C

christopherlmarshall

Fredrik said:

I see. Thanks for the link.

So putting two underscores in front of an instance variable (or any
identifier used inside the scope of a class statement) invokes a name
mangling mechanism ( __x becomes __classname_x internally)

so the following would not result in any conflicts

class A:
def __init__(self):
self.__i= 0

class B(A):
def __init__(self):
A.__init__(self)
self.__i= 1

Is it commonplace to use underscores when defining derived class
instance variables, or is this considered against the grain of python?

Chris Marshall
 
B

Ben Finney

Suppose you want to write a subclass of some existing class you are
importing from a module you didn't write and that you don't want to
study the internals of

No need to study its internals. Fire up a Python interpreter and
inspect its outside:

Any attributes named there should be avoided in your subclasses if you
don't want to clobber existing behaviour.
 
B

bruno at modulix

So putting two underscores in front of an instance variable (or any
identifier used inside the scope of a class statement) invokes a name
mangling mechanism
(snip)

Is it commonplace to use underscores

I assume you mean double underscore...
when defining derived class
instance variables,
or is this considered against the grain of python?

I don't know if it's 'commonplace', but that's something I only do when
I absolutely want to protect a given attribute of a base class from
being accidentally overriden by a derived class. Else I use the usual
convention ('_name' => implementation, 'name' => API), and assume users
of my code will read the documentation (or the source FWIW) before
subclassing. Note that since 'users of my code' are mostly my coworkers
and I, this is a quite sensible assumption !-)
 
C

christopherlmarshall

I see what you mean now.

It would indeed be enlightening if I wanted to study the internals of
Tkinter, and perhaps one day I will.
 
C

christopherlmarshall

Your suggestion ('_name' -> implementation, 'name' -> API) makes sense
as a convention between programmers that know a fair amount about each
other's classes before using them.

I don't think it is reasonable in general to only subclass from base
classes you have studied the full API of, however. The double
underscore is a decent solution to my problem.

I imagine it must be used a lot in domains where people are making
heavy use of third party python code.

Chris Marshall
 
A

Alex Martelli

I don't think it is reasonable in general to only subclass from base
classes you have studied the full API of, however. The double

I think you underestimate the level of coupling that inevitably occurs
between base and derived classes. In general, such coupling being
strong, knowing the full API of the base class is inevitable (although
in some special corner-case, when you do only need to add private data,
you may, exceptionally, get away with less knowledge).


Alex
 
B

Bruno Desthuilliers

(e-mail address removed) a écrit :
Your suggestion ('_name' -> implementation, 'name' -> API)

This is not "my" convention, it's *the* (mostly agreed upon) Python
convention. Like 'self', or CONSTANT, or a whole lot of things in Python.
makes sense
as a convention between programmers that know a fair amount about each
other's classes before using them.

No need to know much. dir(modulename.ClassName) is enough.
I don't think it is reasonable in general to only subclass from base
classes you have studied the full API of, however.

Depends on your definition of "studying the full API" !-)

Now if your fear is to accidentally override something in the base
class, it's just a matter of:
print "API:"
print [name for name in dir(modulename.ClassName) \
if not name.startswith('_')]

print "IMPLEMENTATION:"
print [name for name in dir(modulename.ClassName) \
if not name.startswith('_')]
The double
underscore is a decent solution to my problem.

Possibly. It can also become a PITA. But it's you who know what your
code need !-)
I imagine it must be used a lot in domains where people are making
heavy use of third party python code.

I almost never used it (perhaps half-a-dozen times, and only in
frameworks abstract base classes), and rarely saw it in 3rd part source
code.
 
S

Steven Bethard

so the following would not result in any conflicts

class A:
def __init__(self):
self.__i= 0

class B(A):
def __init__(self):
A.__init__(self)
self.__i= 1

Be careful here. The above won't result in any conflicts, but related
cases, where you have two classes with the same name in different
modules, may still result in conflicts. See my previous posts on this:

http://groups.google.com/group/comp.lang.python/msg/503984abaee1c2b5
http://groups.google.com/group/comp.lang.python/msg/f03183a2c01c8ecf

However, I tend not to use double-underscore name mangling, and I don't
think I've ever had a shadowing problem, so clearly I wouldn't have
shadowing problems with double-underscore name mangling either...

STeVe
 

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

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,901
Latest member
Noble71S45

Latest Threads

Top