Python equivalent for C module

Steven D'Aprano steve at
Tue Oct 21 00:43:55 CEST 2008

On Mon, 20 Oct 2008 17:09:25 -0400, Derek Martin wrote:

> On Mon, Oct 20, 2008 at 07:29:16PM +0200, Bruno Desthuilliers wrote:
>> This should have been:
>>     fprintf(STDERR, "DEBUG: %s", msg);
> No, it shouldn't have.  If I turn on debugging, I  want the debug
> messages to go to stdout, so that they can be captured along with the
> output (of which there is almost none anyway) to clearly indicate when
> they happened.

I agree with this: debugging messages aren't errors, and shouldn't go to 

>> >Then in the modules that wanted to use it, I did:
>> >
>> >from debug import DEBUG, dprint
>> >But I got some weird behavior.  The imported copy
>> It's not a copy.
> Actually, I'm pretty sure it is; i.e. there are two copies of the name:
> one in the namespace of the module, and one in the namespace of the file
> into which I imported it.  

Names are not first class Python objects. You can't pass a name to a 
function and say "do something to this *name*, not the object".

(Of course you can pass a string that happens to match the name to exec, 
but that's not the same thing.)

If you dig around in globals() or locals(), you will find strings 'DEBUG' 
and 'dprint', but they aren't "names". They're just the strings that 
represents the names, and it turns out that CPython caches many (all?) 
such strings which look like identifiers, so there probably is literally 
one and only one string 'DEBUG' no matter how many times you import the 

All of this is just splitting hairs, because you don't really mean Python 
is making a copy of the name 'DEBUG', but of the *data* that DEBUG refers 
to, namely the object True. And it turns out that True is a singleton: 
there is only ever one object True.

But even if DEBUG was set to some other value, say [1, 2, 3, 'x'], you'd 
still be wrong, because Python promises never to copy objects unless you 
explicitly tell it to. There are a number of ways to prove this, but 
perhaps this is the simplest:

DEBUG = [True]  # a mutable list

Now from your calling code, do this:

from module import DEBUG
DEBUG[0] = False  # mutate the object, don't rebind the name

> At the time they are created, they both point
> to the same object.  Is that not the very definition of a copy?

No. It would be a copy if they pointed to different objects, where one 
object was a copy of the other.

> The
> object itself may exist only in one place, 

which is exactly why there is no copy. It's the same object.

> but it has two names; one in each namespace.
>> >of DEBUG is
>> >read-only;
>> It's not read-only.
> The *object* very much is: it is immutable.

So what? The *name* DEBUG is not read-only.

> The name of that object is
> DEBUG, and thus DEBUG is read-only.

But it clearly isn't read-only, because as you yourself point out:

> You can make DEBUG point to a
> different object by binding a different value to it

> Right, several people have already pointed this out.  Which leads me to
> believe that the point of your reply was to berate me into following
> your conventions, which I have no interest in doing, in part because
> they are counterproductive to my goals, and in part because they are
> counter to the way I've been programming for 25 years. Fortunately, it's
> not your call how I write my code.

No, and it's not your call what advice people give you. If you refuse to 
follow good Pythonic advice because you prefer the way you learned 
programming a quarter century ago (before Python even existed), please go 
right ahead, but don't be surprised if people consider you a lousy Python 

>> Now note that ALL_UPPER names are - by convention - considered
>> 'constants'. If this is supposed to be altered, don't write it
> YOUR convention, not mine.

Actually it is a very common convention in Python circles. I often use it 
myself. However it's not the only one, and from time to time I use 
others. I would consider using DEBUG unusual, but not excessively so.

>> Also and FWIW, Python has a logging module in it's stdlib. Please use
>> it instead of any half-backed squared-wheel homegrown solution.
> Note that the correct possessive form of "it" is "its" with no
> apostrophe.  This was the only thing of value which you contributed,
> though really, using that is way overkill for my needs.  If I've written
> bad code, by all means, please correct it.  If I've written code in a
> style that you happen not to like, please feel free to keep that to
> yourself.

Deary deary me... you come along here, asking noob Python questions, and 
then get shirty when people give you friendly and perfectly good answers. 
Are you trying to ensure that the next question you ask remains 


More information about the Python-list mailing list