As currently being discussed in this question, I am writing inclusive versions of the built-in range
and xrange
functions. If these are placed within a module named inclusive
, I see two possible ways to name the functions themselves:
Name the functions inclusive_range
and inclusive_xrange
so that client code can use them as follows:
from inclusive import *
...
inclusive_range(...)
Name the functions range
and xrange
:
import inclusive
...
inclusive.range(...)
To me, the second example of client code looks better, but should I avoid re-using built-in names in this way?
This turned into a bit of a list of different options, rather than a straight answer. However, two concepts are paramount:
range
and xrange
if they explicitly choose to; butrange
and xrange
;it should always be clear to readers of their code where the built-ins are used and where the replacements are used.
For that reason, all options I've outlined below prevent a wildcard import (from inclusive import *
) from shadowing the built-ins. Which is the best option for you depends on whether you see replacing the built-ins as a primary or secondary use of your module. Will users generally want to replace the built-ins, or use them alongside each other?
In your position, I think I would do the following:
inclusive.py
:
"""Inclusive versions of range and xrange."""
__all__ = [] # block 'from inclusive import *'
old_range, old_xrange = range, xrange # alias for access
def range(...): # shadow the built-in
...
def xrange(...): # ditto
...
This allows users to either:
import inclusive
and access inclusive.range
and inclusive.xrange
;from inclusive import range, xrange
, clearly replacing the built-ins without any unpleasant side effects; orfrom inclusive import range as irange, xrange as ixrange
to use the built-in and replacement versions alongside one another.Defining __all__
as an empty list means that from inclusive import *
won't quietly shadow the built-ins.
If you really wanted to, you could add:
irange, ixrange = range, xrange
to the end of inclusive.py
and modify the __all__
definition to:
__all__ = ['irange', 'ixrange']
Now the users have two additional choices:
from inclusive import irange, ixrange
(slightly simpler than manually aliasing the functions as in option 3 above); andfrom inclusive import *
(same result as above, still no implicit shadowing of built-ins).Of course, you could go completely the other way - name your own versions irange
and ixrange
, then if the user really wants to replace the built-ins they would have to:
from inclusive import irange as range, ixrange as xrange
This doesn't require you to define __all__
to avoid a wildcard import shadowing the built-ins.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With