Discussion:
[Tutor] _ vs. _name vs. __name vs. name_ vs. __name__ usages
boB Stepp
2015-07-25 21:08:03 UTC
Permalink
After having a long discussion with my wife on her user requirements,
I am convinced that an OO approach is required. Which is just as well
as that has been one of my next areas of learning to do. I am
currently reading "Python 3 Object Oriented Programming" by Dusty
Phillips, which so far seems to be a reasonably good text. This has
led me to the subject line topics.

From my understandings to date:

1) A single underscore is used conventionally for a "throw-away"
variable, such as a loop index for which the index value is not
actually used in a subsequent calculation.

2) _name is used inside class methods to indicate that the
programmer's intention is that this name should only be accessed
internally by that particular class. Other supposedly "adult" Python
programmers will attempt to respect this original intent if they use
my code.

3) __name invokes Python's name mangling mechanism. The intent of
this usage is to not allow subclasses of the class containing __name
to access this name, and to add additional emphasis to future users of
my code that this name is meant to be strictly hands-off.

4) name_ is used when one is "forced" to use one of Python's reserved
words as a name.

5) __name__ is meant to be used only by the creators of Python for
their special built-in methods, such as __init__, __new__, etc.

Are my understandings above correct or flawed?

For (3), it seems to me that one would normally be able to use the
simpler _name construction from (2). What would be a best-practice
example of when name mangling *should* be used?

Likewise, it seems that normally (4) should never be needed, though I
have a feeling that I have seen something in tkinter recently that
suggests some exceptions, but I cannot (yet) bring it to mind.

And for (5), surely I should never violate this one? It seems that in
some future edition of Python they might add any particular __name__
that I might try to use presently in their future version of Python
(however miniscule that possibility might actually be).

Thanks!
boB
--
boB
_______________________________________________
Tutor maillist - ***@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor
Laura Creighton
2015-07-25 21:42:07 UTC
Permalink
Post by boB Stepp
After having a long discussion with my wife on her user requirements,
I am convinced that an OO approach is required. Which is just as well
as that has been one of my next areas of learning to do. I am
currently reading "Python 3 Object Oriented Programming" by Dusty
Phillips, which so far seems to be a reasonably good text. This has
led me to the subject line topics.
1) A single underscore is used conventionally for a "throw-away"
variable, such as a loop index for which the index value is not
actually used in a subsequent calculation.
Some people do this. I find it irritatingly twee, and hard to read
as well. I like 'junk' for such things.
Post by boB Stepp
2) _name is used inside class methods to indicate that the
programmer's intention is that this name should only be accessed
internally by that particular class. Other supposedly "adult" Python
programmers will attempt to respect this original intent if they use
my code.
The world is packed very full of Python programmers who have never
heard of this rule, and thus this is sort of a 'pious hope' more
than anything else. The world is also full of python modules that
have no single underscore variable names at all.
Post by boB Stepp
3) __name invokes Python's name mangling mechanism. The intent of
this usage is to not allow subclasses of the class containing __name
to access this name, and to add additional emphasis to future users of
my code that this name is meant to be strictly hands-off.
worry about this when you want to share your code with the world
and don't want new users to be able to rely on things to always be
the way you have it right now.

i.e. adding double underscores is often the last thing you do
before release.
Post by boB Stepp
4) name_ is used when one is "forced" to use one of Python's reserved
words as a name.
You are never forced to. Sometimes you might want to. Sometimes
name_ is a good choice in this case. But in my life 'stop
wanting this, you arrogant wretch' has mostly been the correct
thing. :) (At least I think never. Maybe I am being an arrogrant
wretch here, too.)
Post by boB Stepp
5) __name__ is meant to be used only by the creators of Python for
their special built-in methods, such as __init__, __new__, etc.
Are my understandings above correct or flawed?
Pretty much dead on.
Post by boB Stepp
For (3), it seems to me that one would normally be able to use the
simpler _name construction from (2). What would be a best-practice
example of when name mangling *should* be used?
If you do not mangle the names, you are making a promise, sometimes
a half-hearted promise, that through the life of the code
other people can come by and use these methods, with exactly
this signature, and it will just work. This is called 'being
Part of the public API'. If you publish such things and then,
next release, remove those methods or change the number or
order of the arguments .... their code will break.

If its just you and your tapeworm, you don't care and you make and
remove methods and signatures all the time. If people do not like it,
tough, and so it goes. It's what they get for running your experimental
software.

If you publish your code as a module on PyPI people will find ways to
use the public API, so if you want to reserve the right to delete
this method later, or change it's signature then by all means mangle
the thing.

In the Python world people are generally less worried about what
will happen if some wretch gets a hold of a method that I didn't
really want as part of the public API than what will happen
if they badly need to get a hold of a method and I didn't make
it possible. This makes for a lot of the single underscore
variables. 'I don't want to make it impossible for you to
access things this way, but I wish you wouldn't' more or less.
Post by boB Stepp
Likewise, it seems that normally (4) should never be needed, though I
have a feeling that I have seen something in tkinter recently that
suggests some exceptions, but I cannot (yet) bring it to mind.
Not sure what you are thinking about.
Post by boB Stepp
And for (5), surely I should never violate this one? It seems that in
some future edition of Python they might add any particular __name__
that I might try to use presently in their future version of Python
(however miniscule that possibility might actually be).
Right. Don't go there.
Post by boB Stepp
Thanks!
boB
--
boB
MY .02 euros.

Others will have other ideas.

but that is the way I see it.

Laura

_______________________________________________
Tutor maillist - ***@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor
Zachary Ware
2015-07-25 21:58:32 UTC
Permalink
Post by boB Stepp
5) __name__ is meant to be used only by the creators of Python for
their special built-in methods, such as __init__, __new__, etc.
Everything up to this point was pretty accurate. You're only half
right with this one, though; __dunder__ names are ones that you should only
use when hooking into the "magic" of the interpreter. That is, you should
not define your own __dunder__ names, but feel free to use ones that have
been defined by the implementation and documented as the way to do
something. For example:

class Spam:
def __init__(self, value):
self.value = value

def __getitem__(self, key):
return self.value

assert Spam(42)['eggs'] == 42

__getitem__ is the documented method to implement to allow instances of
your class to be indexed like a list or dict.

Are my understandings above correct or flawed?
Post by boB Stepp
For (3), it seems to me that one would normally be able to use the
simpler _name construction from (2). What would be a best-practice
example of when name mangling *should* be used?
I have yet to ever see a place where name mangling was warranted. I have
been severely annoyed by it before, though. To make a particular class work
the way I wanted it to, I had to subclass it and explicitly override a
couple of mangled names. In my opinion, name mangling should never be used
unless overriding the value will set your CPU aflame.

Likewise, it seems that normally (4) should never be needed, though I
Post by boB Stepp
have a feeling that I have seen something in tkinter recently that
suggests some exceptions, but I cannot (yet) bring it to mind.
There are a couple of methods in tkinter that accept an 'in_' keyword
argument, where in Tcl it is documented as 'in', which is a Python
keyword. In code that's not interfacing with something else that uses a
Python keyword, it's usually best to just find a different name.

And for (5), surely I should never violate this one? It seems that in
Post by boB Stepp
some future edition of Python they might add any particular __name__
that I might try to use presently in their future version of Python
(however miniscule that possibility might actually be).
Right, don't make up your own __dunder__ names.

Hope this helps,

--
Zach
(On an iPad)
--
Sent from Gmail Mobile
_______________________________________________
Tutor maillist - ***@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor
Mark Lawrence
2015-07-26 00:51:19 UTC
Permalink
Post by boB Stepp
After having a long discussion with my wife on her user requirements,
I am convinced that an OO approach is required. Which is just as well
as that has been one of my next areas of learning to do. I am
currently reading "Python 3 Object Oriented Programming" by Dusty
Phillips, which so far seems to be a reasonably good text. This has
led me to the subject line topics.
1) A single underscore is used conventionally for a "throw-away"
variable, such as a loop index for which the index value is not
actually used in a subsequent calculation.
It is not a convention, it is inbuilt. It is very useful as linter type
tools don't complain about you defining something but not using it.
Post by boB Stepp
2) _name is used inside class methods to indicate that the
programmer's intention is that this name should only be accessed
internally by that particular class. Other supposedly "adult" Python
programmers will attempt to respect this original intent if they use
my code.
Correct.
Post by boB Stepp
3) __name invokes Python's name mangling mechanism. The intent of
this usage is to not allow subclasses of the class containing __name
to access this name, and to add additional emphasis to future users of
my code that this name is meant to be strictly hands-off.
4) name_ is used when one is "forced" to use one of Python's reserved
words as a name.
I don't know about reserved words but it is certainly used rather than
override a built-in name.
Post by boB Stepp
5) __name__ is meant to be used only by the creators of Python for
their special built-in methods, such as __init__, __new__, etc.
Correct.
Post by boB Stepp
Are my understandings above correct or flawed?
For (3), it seems to me that one would normally be able to use the
simpler _name construction from (2). What would be a best-practice
example of when name mangling *should* be used?
I'd be inclined not to bother yourself with this. I've never used it in
the centuries that I've been writing Python, and somebody who is
determined enough can work around it anyway owing to Python's dynamic
nature.
Post by boB Stepp
Likewise, it seems that normally (4) should never be needed, though I
have a feeling that I have seen something in tkinter recently that
suggests some exceptions, but I cannot (yet) bring it to mind.
If you like a name enough and cannot think of a better alternative why not?
Post by boB Stepp
And for (5), surely I should never violate this one? It seems that in
some future edition of Python they might add any particular __name__
that I might try to use presently in their future version of Python
(however miniscule that possibility might actually be).
Definitely.
Post by boB Stepp
Thanks!
boB
No problem. Once again my invoice is in the post, your cheque by return
please :)
--
My fellow Pythonistas, ask not what our language can do for you, ask
what you can do for our language.

Mark Lawrence

_______________________________________________
Tutor maillist - ***@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor
Ben Finney
2015-07-26 01:14:30 UTC
Permalink
Post by boB Stepp
1) A single underscore is used conventionally for a "throw-away"
variable, such as a loop index for which the index value is not
actually used in a subsequent calculation.
That accurately describes common usage. But it's important to also know
that ‘_’ has numerous conflicting common usages (including a widely-used
text translation function).

Less common, but IMO much more preferable for “don't actually want this
value but need to bind something to it”, is the convention ‘__’ as a
name::

for (__, important_value) in sequence_of_tuples:
...

The name ‘__’ doesn't AFAIK have conflicting usages (therefore more
strongly connoting this meaning), is pretty easy to type and much easier
to spot than a single underscore.
Post by boB Stepp
2) _name is used inside class methods to indicate that the
programmer's intention is that this name should only be accessed
internally by that particular class.
Not so much “inside class methods”; rather, the names are on attributes
of a class (or module or, sometimes, function).

This is the convention for “even if you can see this attribute, it is an
implementation detail, not part of the public API for this class,
anything might change about this in future revisions”.

With no leading underscore, the implicit promise is that the name is a
published API for the code, and can be relied on to keep the same name
and behaviour in future revisions of the code.
Post by boB Stepp
3) __name invokes Python's name mangling mechanism. The intent of this
usage is to not allow subclasses of the class containing __name to
access this name, and to add additional emphasis to future users of my
code that this name is meant to be strictly hands-off.
[…] it seems to me that one would normally be able to use the
simpler _name construction
Right. I've felt any need to use this in my Python programming career;
the distinction between “public API” (‘foo’) versus “implementation
detail” (‘_foo’) is plenty.
Post by boB Stepp
4) name_ is used when one is "forced" to use one of Python's reserved
words as a name.
Yes. It's a last resort, IMO, but a valuable one; and the only damage is
to readability (difficult to distinguish when reading quickly).
Post by boB Stepp
it seems that normally (4) should never be needed, though I have a
feeling that I have seen something in tkinter recently that suggests
some exceptions, but I cannot (yet) bring it to mind.
The Python keywords and built-in object names include some obvious,
common words. This is a clear benefit, but it can also cause a clash
when choosing your own names: some of the best ones are already taken.

I've seen this used to name ‘assert_’, ‘file_’, and the like.
Post by boB Stepp
5) __name__ is meant to be used only by the creators of Python for
their special built-in methods, such as __init__, __new__, etc.
[…] surely I should never violate this one? It seems that in
some future edition of Python they might add any particular __name__
that I might try to use presently in their future version of Python
(however miniscule that possibility might actually be).
Yes. Never name anything with this ‘__foo__’ style unless Python already
will treat it specially, and your intention is to invoke that special
treatment by Python.

This convention is violated too often in third-party code for names that
don't have any special significance to Python, leading to needless
confusion about how special a newly-encoutered name really is. All the
ones I've seen in third-party code would always be improved for clarity
by choosing a normal ‘foo’ or ‘_foo’ name.
Post by boB Stepp
Are my understandings above correct or flawed?
I hope that helps.
--
\ “It's dangerous to be right when the government is wrong.” |
`\ —Francois Marie Arouet Voltaire |
_o__) |
Ben Finney

_______________________________________________
Tutor maillist - ***@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailm
Cameron Simpson
2015-07-27 23:42:13 UTC
Permalink
Post by boB Stepp
After having a long discussion with my wife on her user requirements,
I am convinced that an OO approach is required. Which is just as well
as that has been one of my next areas of learning to do. I am
currently reading "Python 3 Object Oriented Programming" by Dusty
Phillips, which so far seems to be a reasonably good text. This has
led me to the subject line topics.
Broadly everything you have said is correct.
Post by boB Stepp
1) A single underscore is used conventionally for a "throw-away"
variable, such as a loop index for which the index value is not
actually used in a subsequent calculation.
Yes, but there are some problems. Some don't like it, and it can conflict with
other uses. I use it very rarely, almost only ever in very simple list
comprehensions, such as this real example:

self.hashlist = [None for _ in range(maxchunks)]

which primes a list of None values.

Using it in a wider context like a loop has the same issues as any other
"trite" variable name: that you will reuse it later and forget that it is
either already in play (eg nested loops) or already initialised (eg code later
break because of some presumption it is not set up).

It is almost always better, if only for readability, to pick a sensible name,
like "i", even if it is not used. A short name like "i" pretty much says "this
is used only here, because otherwise I would have used a longer name that has
more context".

Of course, the flip side of that is that "_" _is_ the name that says "not used
elsewhere", and thus if you use it in in an expression t should scream
"mistake" at you. So this:

[ (i,) for i in range(10) ]

to make a list of tuples (made up example) should not be used with "_" instead,
as "i" does get used.

So yes, correct, but many people use it very sparingly and some avoid it
altogether.
Post by boB Stepp
2) _name is used inside class methods to indicate that the
programmer's intention is that this name should only be accessed
internally by that particular class. Other supposedly "adult" Python
programmers will attempt to respect this original intent if they use
my code.
Or by cooperating classes. But only _closely_ cooperating classes that have
knowledge of your first class' internals, usually because they muck with them
directly. Basicly, a _name is held to be part of the private API, and subject
to change.

So code which is prepared to be broken by changes might use it, such as if you
have a pair of classes which both muck _directly_ with some shared data
structure.

Note than in pure OO one class never mucks with another class' internals; they
only ever communicate via methods.
Post by boB Stepp
3) __name invokes Python's name mangling mechanism. The intent of
this usage is to not allow subclasses of the class containing __name
to access this name, and to add additional emphasis to future users of
my code that this name is meant to be strictly hands-off.
Yeah. I have pretty much ceased using this. It causes pain and doesn't fulling
solve the problems.

The usual use case is subclassing:

class Shape(object):

def __init__(name):
self.name = name
self.__count = 0

def inc(self):
self.__count += 1

class Cube(Shape):

def __init__(name):
Shape.__init__(name)
self.__count = 6

def add_face(self):
self.__count += 1

Internally there two classes work on "__Shape_count" and "__Cube_count", and
thus avoid stepping on each others' toes, because although each wants a counter
with a nice simple name, they mean very different things with it. So you Cube
class has two separate counters.

But the names are arguably uglier and harder to type.

Also, consider this:

from my_geometry_module import Shape as UrShape

class Shape(UrShape):

def __init__(self, name):
UrShape.__init__(name)
self.__count = 5

def bfmi(self):
self.__count -= 1

class Pyramid(Shape):
...

Here, your local "Shape" class will _also_ use "__Shape_count", and _will_ have
trouble. So this system is not totally robust. While the example above is
contrived, a deeper nesting of classes might easily have the same issue because
the final class may not be aware that a class of the same name is already in
use higher up the chain.
Post by boB Stepp
4) name_ is used when one is "forced" to use one of Python's reserved
words as a name.
Yes, quite command. Also for predefined names as well as reserved names. My
commonest use is the name "type", which is no a reserved word (i.e. special in
the language grammar, like "if") but predefined as the "what is the type of
this object" function. I've got a few objects floating around where a ".type"
attribute is a natural name to indicate their flavour. That works just fine.
But when I want to access the object, "type" is also a natural name for the
parameter:

def check_type(self, type):
return self.type == type

While that works, it means you have lost access to the predefined Python type()
function inside that bit of code. Which can be bad. Even if you do not use the
function, it makes your code confusing for other programmers (== you several
months later) because they have an expectation of its meaning.

Way of addressing this all involve just using another name. Common ways include
"name_", "n" (trivial short term variable) or a misspelling. For example,
saying "klass" instead of "class".
Post by boB Stepp
5) __name__ is meant to be used only by the creators of Python for
their special built-in methods, such as __init__, __new__, etc.
Yes, but in the sense that they have predefined meanings. If you are
implementing a mapping (a class that has methods and access like a dictionary),
you will need to define methods using these names to implement the API.

So don't make up your own!
Post by boB Stepp
Are my understandings above correct or flawed?
Yes.
Post by boB Stepp
For (3), it seems to me that one would normally be able to use the
simpler _name construction from (2). What would be a best-practice
example of when name mangling *should* be used?
Well, people rarely use _name as a function parameter, unless it is a
private/secret parameter for special internal use.

So I would write this:

def check_type(self, type_):
return self.type == type_

instead of using "_type". because "type_" here is a _public_ parameter for
people to use. Using "_type" would mislead.
Post by boB Stepp
Likewise, it seems that normally (4) should never be needed, though I
have a feeling that I have seen something in tkinter recently that
suggests some exceptions, but I cannot (yet) bring it to mind.
(4) is never required, but is often convenient.
Post by boB Stepp
And for (5), surely I should never violate this one? It seems that in
some future edition of Python they might add any particular __name__
that I might try to use presently in their future version of Python
(however miniscule that possibility might actually be).
Yes: don't make up new __name__s. But you will _implement_ some __name__s at
some point.

Cheers,
Cameron Simpson <***@zip.com.au>

On the one hand I knew that programs could have a compelling and deep logical
beauty, on the other hand I was forced to admit that most programs are
presented in a way fit for mechanical execution, but even if of any beauty at
all, totally unfit for human appreciation. - Edsger W. Dijkstra
_______________________________________________
Tutor maillist - ***@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor
Alan Gauld
2015-07-28 09:08:52 UTC
Permalink
Post by boB Stepp
4) name_ is used when one is "forced" to use one of Python's reserved
words as a name.
Various others have commented on the use cases for this. I'd just add
that my solution to using a name that's already used by the language (or
even already used by my project) is to attach an article prefix such as
'my':

Thus instead of using 'type_' I'd use 'my_type' or 'the_type'.

I also do this a lot in parameter lists of functions/methods so:

def someMethod(self, aWidget, aDimension):
....

which avoids the common confusion where the parameters are the
same as the names of variables in the calling scope and it
can get confusing as to whether references inside the method
are to parameters or global names.

In particular in class definitions I often use theXXX for a
class attribute name, myXXX for an instance attribute name,
and aXXX for the parameter of a method.

This is not nearly so important in Python because you have to
use self.xxx to get the attribute (and use Class.xxx for
class attributes) but in other OOP languages where self
is not required I find it helps a lot.

I work quite hard to avoid names with dangling underscores because:
1) They look like an error - somebody forgot to type half the name!
2) Depending on font its hard to differentiate single and
double underscores.
3) They make reading the code aloud (eg over the phone during
a late night call-out!) much more difficult.
--
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos


_______________________________________________
Tutor maillist - ***@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor
Continue reading on narkive:
Loading...