18

I have made a mistake as below:

>>> list = ['a', 'b', 'c']

But now I want to use the built-in function list(). As you can see, there is a naming conflict between listname list and the built-in function list().

How can I use list as a built-in function not the variable without restarting the Python shell?

Ajean
  • 5,528
  • 14
  • 46
  • 69
holys
  • 13,869
  • 15
  • 45
  • 50
  • 3
    nice question, we should link to this whenever people use a builtin name – jamylak May 13 '13 at 13:55
  • 2
    Worth noting: probably the best thing for you to do is to use one of the methods below to access the built-in version, and rebind the `list` name to it, to undo your mistake. `list = __builtins__.list` – Henry Keiter May 13 '13 at 14:00

7 Answers7

32

Step one: rebind the list to a different name

lst = list

Step two: delete the list variable

del list

Step three: don't do it again


I prefer this over __builtins__.list simply because it saves the typing, and you aren't still left with a variable named list. However, it is always best to avoid the problem altogether. When writing production code, always remember not to have variables named the same as built in functions.

Volatility
  • 31,232
  • 10
  • 80
  • 89
  • 2
    This is an excellent answer. In addition to the advantages you mentioned, it does not rely on CPython implementation details! – Adam May 13 '13 at 14:07
  • Sorry, this is a bad answer in my book. -1. It is definitely a possibility, but it is going against what I believe is the sensibility of coding. This causes your code to be disjointed from other Python everywhere, Anyone looking at segments of the code would becomes confused, and it would not work well with other modules. In other words- this would BREAK constantly and be VERY fragile. – Inbar Rose May 13 '13 at 14:09
  • 13
    @InbarRose The question specifically applies to the Python interpreter shell. Using *any* of the hacks provided in these answers would be *crazy* in production code—and by that, I mean any code that is written outside of the live interpreter. – Adam May 13 '13 at 14:11
  • 3
    `How can I use list as a built-in function not a list variable without restart the Python shell?` @InbarRose - this is probably the easiest to type in the shell and also remembers to mention to re-bind the existing variable to something else first... (not just getting `list` back) – Jon Clements May 13 '13 at 14:12
  • Sorry, you won't convince me. This is just bad, but I do realize I downvoted you and not others, so I will undo that. – Inbar Rose May 13 '13 at 14:15
  • 2
    @InbarRose You don't seem to be taking into account the context of the question. – Gareth Latty Jul 21 '13 at 10:13
  • By accident I did exactly the same thing for `len` and followed this suggestion. I still encounter an error: `UnboundLocalError: local variable 'len' referenced before assignment` – Regis May Jun 30 '16 at 09:28
  • This doesn't work if `list` is a function argument. `UnboundLocalError: local variable 'list' referenced before assignment`. Seems like a bug in CPython to me. – Braden Best Aug 23 '18 at 17:19
31

Use __builtins__.list or __builtins__['__list__'] (depending on context), or simply delete list again (del list).

No imports needed:

>>> __builtins__.list
<type 'list'>

The presence of __builtins__ is a CPython implementation detail; in the __main__ module it is a module, everywhere else it is the module __dict__ dictionary. Jython, IronPython and PyPy may opt to not make this available at all. Use the __builtin__ module for those platforms, or for Python 3 compatible implementations, the builtins module:

>>> import __builtin__
>>> __builtin__.list
<type 'list'>
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • 7
    Re: `__builtins__.list` - don't do this. Just because you can doesn't mean you should. – FogleBird May 13 '13 at 14:02
  • 3
    @FogleBird Given the situation the OP gives - a mistake at the interpreter, I don't think there is anything wrong with doing this. Obviously in any code written in a file, it's a different case. – Gareth Latty Jul 21 '13 at 10:10
9

Do not use built-in functions, or types as variable names. It is just as simple as that, the language is not meant for that. And it makes no sense to do so.

Not only that - but using the name "list" for a list is very ambiguous, and I doubt it is even remotely usable in any real code.


There are a few reasons why you should NOT ever shadow a built-in. Some of the more serious ones are below:

  • Compatibility, the code would not work with other modules.
  • Confusion, anyone reading your code will not understand what is going on.
  • Circumstances, many of the built-ins use other built-ins, changing one can have unexpected results on other aspects of code.
Inbar Rose
  • 41,843
  • 24
  • 85
  • 131
  • 7
    This does not answer the question - the OP understands that what he did was wrong, but he is using the shell and wants to fix the mistake. – Gareth Latty Jul 21 '13 at 10:11
  • Is there some way to make the Python interpreter issue a warning and/or terminate when using these builtin function names as variable names? As is the case when using keywords as variable names? Some initial command in the script making the interpreter more picky? – Oortone Nov 26 '21 at 15:21
4

To repair the mistake, there is another option - if we remember that the built-in 'function' list() is actually a class, then we can just do this:

list = type([])
Gareth Latty
  • 86,389
  • 17
  • 178
  • 183
  • So what do you do when you overwrite `type`? Because that's exactly my situation: I have a class with a `type` attribute, and I need to resolve the ambiguity in `__init__` while still allowing the caller to call with, e.g. `Transaction(type = Transaction.T_SINGLE)`. I can't use a different name like `_type`, because I'm implementing an API, and `type`, being a function argument to `__init__`, is user-facing. You'd think deleting `type` in the function would work as it does on the global scope, but it causes python to crash on an ostensibly *erroneous* `UnboundLocalError` instead. – Braden Best Aug 23 '18 at 17:27
  • So what I ended up doing is making a "backup" in the class named `_typeof`. I used the name `_typeof` so that it's obvious that the intent is type checking (ala JavaScript); the underscore is to hopefully prevent others from confusing it with JavaScript's `typeof` operator. Referenced as `Transaction._typeof(...)` – Braden Best Aug 23 '18 at 17:44
  • @BradenBest The correct answer is definitely *don't*. If you are making an API then calling something `type` infects other people's code with that bad idea. If it's already been shipped and you have to maintain compatibility, then yes "backing up" is a perfectly fine strategy. Python does also provide [`builtins`](https://docs.python.org/3/library/builtins.html) as another way to get these back, but that is generally more overhead than just doing what you suggested (it's mostly useful in the interactive shell). – Gareth Latty Aug 23 '18 at 20:59
  • Ah, but if you're using python 2.x, there is no guarantee that you'll be able to use it. `builtins` is a 3.x module made to address 2.x's `__builtins__`, which is a Cpython extension and not part of the standard library. This would be fine and dandy if `builtins` could be imported from `__future__`, but...yeah. That said, I wasn't happy with the workaround, so I ended up changing the function signature `__init__(self, price, [...], type)` -> `__init__(self, data)`, where `data` is a dict. This (mostly) preserves the API while making serialization to/from JSON straightforward. – Braden Best Aug 23 '18 at 21:27
2

use __builtin__.list in py2x:

>>> import __builtin__ 
>>> __builtin__.list
<type 'list'>

Don't use __builtins__.list :

From the docs:

CPython implementation detail: Users should not touch __builtins__; it is strictly an implementation detail. Users wanting to override values in the builtins namespace should import the __builtin__ (no ‘s’) module and modify its attributes appropriately.

for py3x:

>>> import builtins
>>> builtins.list
<class 'list'>
Ashwini Chaudhary
  • 244,495
  • 58
  • 464
  • 504
1

It is always available as __builtins__.list:

>>> __builtins__.list
<class 'list'>
>>> list = [1, 2, 3]
>>> __builtins__.list
<class 'list'>

If you happen to rebind that, however, you're out of options.

You can also use the module __builtin__ (or builtins, without the underscores, in Python 3) but you have to import it. But these are different ways to spell the same thing, rather than being an extra option - modifying one affects both:

>>> import builtins
>>> builtins.list
<class 'list'>
>>> builtins.list = [1, 2, 3]
>>> builtins.list
[1, 2, 3]
>>> __builtins__.list
[1, 2, 3]
lvc
  • 34,233
  • 10
  • 73
  • 98
0

Yes, others are saying above, don't use the name of a builtin as a variable name. This goes for list, dict, etc.

Likewise, as others have said, you have access to the type list through __builtins__.list. So if you need to call list, you can still find it, as long as you haven't rebound __builtins__.list also.

Importantly, though, list is a name. You've rebound it to an instance of a list. If you want list to mean <type 'list'> again, just rebind it again. In Python 2.7:

>>> __builtins__.list
<type 'list'>
>>> list
<type 'list'>
>>> list = [1, 2, 3]
>>> list
[1, 2, 3]
>>> fred = list
>>> fred
[1, 2, 3]
>>> list = __builtins__.list
>>> list
<type 'list'>
pcurry
  • 1,374
  • 11
  • 23