Is it bad style to override the built-in function `type`?

Steven D'Aprano steve+comp.lang.python at pearwood.info
Sat Nov 24 23:06:13 EST 2012


On Sat, 24 Nov 2012 14:32:19 -0800, Michael Herrmann wrote:

> Hi,
> 
> how about "write" instead of "type"? Just came to me in a flash of
> inspiration. I know it's also pretty general but at least it's not a
> built-in!

"write" is an extremely common operation with a signature very similar to 
that of your function you want. The typical use of your function:

automata.write("Hello world")  # or whatever your module is called

looks exactly like writing to the file referred to by the name "automata".

Writing to files is *far* more common than using type. Using the standard 
library for a rough-and-ready test:

[steve at ando python3.3]$ grep "[.( ]write(" *.py | wc -l
475
[steve at ando python3.3]$ grep "[.( ]type(" *.py | wc -l
161


If it isn't obvious what I am doing, I am using the Linux "grep" utility 
to search the Python 3.3 standard library for calls to functions or 
methods called "write" vs "type". There are nearly three times as many 
calls to "write".

If I inspect the way that the functions are used, the difference is 
clear: write is nearly always used as a procedure, while type is used as 
a function. Here are a couple of typical examples:

copy.py:    return type(x)(x.__func__, deepcopy(x.__self__, memo))
datetime.py:        if type(other) != timezone:

Your "simulate typing" function does not look like this. It doesn't 
return anything. It usually gets used as a procedure, not a function, 
just like the write method:

base64.py:        output.write(line)
formatter.py:            write(word)

There is far more opportunity for confusion with the name "write" than 
"type":

* writing to files is much more common than calling type, even in
  expert-level code;

* beginners are even less likely to be using builtin type;

* a call to your proposed function "type(string)" does not look 
  like a typical call to the builtin type function;

* but a call to your proposed function "write(string)" does look
  very similar, if not identical, to a typical call to write.


This is why I maintain that fear of shadowing builtins often becomes 
superstition, not reasonable, reasoned advice. For fear of one (unlikely) 
source of confusion, you are prepared to accept a (more likely) source of 
greater confusion.

Writing to files is a very common thing to do. Calling type() is not. Way 
back in the early days of Python, it was common to use code like:

if type(obj) is type([]): ... 

but that is usually wrong (it rejects subclasses) and inelegant. Normally 
people will use:

if isinstance(obj, list): ... 

or better still, avoid type-testing altogether. One thing that *doesn't* 
get done is call builtin type on a literal string, then ignore the result:

type("Hello world!")

What would be the point? That would be better written:

str

or even better still, not written at all, since it does nothing sensible.

But calling file method "write" with a string, or a string literal, is 
extremely common, and sensible. Your proposed "write" will look just like 
writing to a file, when it does something completely different. A couple 
of days ago I said:

[quote]
If it were possible to be confused by the two types, e.g. if they took the
same arguments but did radically different things, then I would accept
that it was too dangerous/confusing to re-use the name. Reasonable fears
about shadowing and confusion are, well, reasonable.
[end quote]


Your proposal to use "write" is exactly the sort of reasonable confusion 
that I was talking about.



-- 
Steven



More information about the Python-list mailing list