[Python-ideas] Hungarian notation [was Welcome ...]

Steven D'Aprano steve at pearwood.info
Fri Apr 15 14:19:02 EDT 2016

(Changing the subject line to something a little more relevant.)

Hi Richard, and welcome.

My repsonses are below, interleaved between your comments as 

On Fri, Apr 15, 2016 at 05:57:05PM +0100, Richard Prosser wrote:

> Is there any mileage in having a naming convention to indicate the type of
> a variable? 

Perhaps not mileage, as such, but maybe yardage or even inchage :-)

Certainly there are naming conventions which are very common:

s for strings;
n for ints;
i, j, k for indexes, especially in a loop;
o or obj for arbitrary objects of any type;
x, y for floats or arbitrary numbers;

etc. They're good for short, generic functions, and it wouldn't surprise 
me if linters and type-checkers had an option to complain if they see 
what looks like misused standard names:

n = 23  # okay
n = {}  # perhaps not?

For less generic functions, we should pick names which describe the 
purpose of the variable. That's usually far more important than it's 
type, especially in languages like Python where *variables* (the names 
themselves) are untyped, only the values assigned to them have types.

> I have never really liked the fact that the Python 'duck
> typing' policy is so lax, yet the new "Type Hints" package for 
> Python 3 is rather clumsy, IMO.

Oh? Can you give an example of type annotations or declarations which 
aren't clumsy?

> For example:
> github_response = requests.get('https://api.github.com/user',
> auth=('user', 'pass'))
>  # Derived from http://docs.python-requests.org/en/master.
> The above request returns a Response
> <http://docs.python-requests.org/en/master/api/#requests.Response> object
> and so the variable has 'response' in its name.

I consider that a perfectly reasonable variable name, since it describes 
the variable and gives an idea of its purpose. The fact that it is of 
type Response is not as important as the fact that it is a response from 
a web-server.

> Likewise:
> word_count = total_words_in_file('text_file')
> where 'count' has been defined (in the IDE, by the user perhaps) as an
> Integer 

Declaring that "count" is an integer doesn't tell us anything about 
"word_count". They're completely different variables.

> and the function is known to return an Integer, perhaps via a local
> 'count' or 'total' variable.

A good type-checker should be able to infer that if total_words_in_file 
returns an int, then word_count is also an int. (At least up to the 
point where it is re-bound to another value.)

> I know that this has been attempted before but I think that an IDE like
> PyCharm could actually check variable usage and issue a warning if a
> conflict is detected.

That's the purpose of MyPy and related projects.

(By the way, for the avoidance of doubt, you should understand that 
Python will never force the use of type annotations or static typing.)

> Also earlier usages of this 'Hungarian Notation' have
> largely been applied to compiled languages - rather strangely, in the case
> of known types - rather than an interpreted one like Python.

You should be aware that there are two forms of Hungarian Notation. One 
is useless and widely despised, and the other is helpful but rarely used 
because it's reputation was ruined by the other kind.


> Please note that I have shown suffixes above but prefixes could also be
> valid. I am not sure about relying on 'type strings' *within* a variable
> name however.

I'm not sure I understand what you mean here.

> Is this idea feasible, do you think?

If you mean, could Python enforce type hints through naming conventions, 
I think not. Do you really want to see code like:

numpages_Integer_Or_None = self.count_pages()

While some form of Hungarian Notation is useful, using it everywhere as 
a type hint is going to get frustrating really fast. A good type hint or 
declaration should happen once:

Declare numpages: Integer|None   # making up some syntax

numpages = self.count_pages()
if numpages is not None:
    for page_num in range(1, numpages+1):
        print("Page %d of %d." % (page_num, numpages))


numpages_Integer_Or_None = self.count_pages()
if numpages_Integer_Or_None is not None:
    for page_num in range(1, numpages_Integer_Or_None+1):
        print("Page %d of %d." % (page_num, numpages_Integer_Or_None))

The second is too tiresome to read and write. Using abbreviations will 
decrease the typing burden, but increase the burden of remembering what 
those abbreviations mean.


More information about the Python-ideas mailing list