Why is it bad to name a variable id
in Python?

- 32,488
- 9
- 84
- 95

- 3,284
- 3
- 23
- 24
-
38Most people append an underscore to identifiers that clash with builtins/keywords: id_, map_, list_, filter_, etc. – cdleary Nov 01 '08 at 23:11
-
7A more sneaky solution would be to use a variable `ID`. – Simon Kuang Jul 09 '15 at 23:56
-
106A better question would be... What genius thought using such a common, generic name for a built-in function was a good idea? – Basic Jul 26 '16 at 14:26
-
1@Basic it's a standard thing that someone would expect the function to be named, according to what it does. The longer `identity` would be ambiguous (since it could also mean a function that accepts one parameter and returns the same value). – Karl Knechtel Mar 17 '23 at 06:30
9 Answers
id()
is a fundamental built-in:
Help on built-in function
id
in module__builtin__
:id(...) id(object) -> integer Return the identity of an object. This is guaranteed to be unique among simultaneously existing objects. (Hint: it's the object's memory address.)
In general, using variable names that eclipse a keyword or built-in function in any language is a bad idea, even if it is allowed.

- 19,975
- 5
- 50
- 78

- 12,436
- 5
- 39
- 47
-
3OK, for 'id' you're right, but the "in general..." comment still applies, don't you think? – Kevin Little Sep 19 '08 at 17:55
-
8I would avoid it for module globals certainly. For variables restricted to local scope, so you can see the same function isn't ever going to need to use the builtin, it's not something I'd worry about. – bobince Feb 02 '09 at 17:13
-
@Caramdir: Good catch, `id` was slated for removal at one time, but eventually they decided not to remove it. I'm no longer able to edit my original comment, so I'll delete it to avoid confusing people in the future. – Eli Courtwright Mar 04 '14 at 14:10
-
51@EliCourtwright I wish they had removed it. What a poorly named method! A generic, common name used in thousands of places (where context gives meaning). So someone decided to use it as a global name where there is no context? – Basic Jul 26 '16 at 14:27
-
3Amazingly, Google's own Python regex tutorial (https://developers.google.com/edu/python/regular-expressions) uses `str = 'an example word:cat!!'`. Is there anything in any of the PEPs that says don't do this? – wordsforthewise Apr 18 '17 at 20:30
-
@wordsforthewise also numpy's `np.array` names the first argument `object`, shadowing the built-in type. I have seen many examples of this, including, if I'm not mistaken, in standard modules. – MattS Feb 21 '19 at 12:19
-
-
1@MattS It's fine as a parameter name though, cause the shadow is inside the function scope, so you don't need to worry about it. The only chance of confusion I can think of is if you use the parameter name outside of the call, like `object = []; np.array(object)`. – wjandrea Jul 18 '20 at 19:28
-
*"In general, using variable names that eclipse a keyword or built-in function in any language is a bad idea, even if it is allowed."* It's more than just a bad idea in python. Most programming languages use scoped variable names; but python uses dynamic variable names. This means that if you shadow a name, you're breaking all code and functions that refer to that name. – Stef Jan 07 '22 at 10:39
In PEP 8 - Style Guide for Python Code, the following guidance appears in the section Descriptive: Naming Styles :
single_trailing_underscore_
: used by convention to avoid conflicts with Python keyword, e.g.
Tkinter.Toplevel(master, class_='ClassName')
So, to answer the question, an example that applies this guideline is:
id_ = 42
Including the trailing underscore in the variable name makes the intent clear (to those familiar with the guidance in PEP 8).

- 18,291
- 25
- 109
- 191
-
3This doesn't answer the actual question, but +1 for the PEP-8 naming convention – ege Jan 29 '19 at 14:23
-
7Good advice, but `id` is a builtin, not a keyword, and this doesn't explain why it's bad to shadow a builtin. – wjandrea Jul 02 '20 at 01:36
-
@wjandrea It's bad to shadow a builtin because it makes the code less readable and harder to maintain. You can freely assign `print = 123` but then you or your coworkers will be surprised later in the code why `print('Hello World')` raises a TypeError. PEP8 gives the recommended way how to name such variable. – Jeyekomon Jun 14 '21 at 16:15
-
-
2@wjandrea PEP8 does not explicitly state how to name your variable in case of conflict with builtin. It is up to you to find some solution that fits you well. You can name your variable with three trailing underscores. But every sane person would use the same naming convention as used in the conflicts with keywords since there is no good reason to alter the naming convention based on what you shadow. I wonder what is so difficult to understand about it. – Jeyekomon Jun 14 '21 at 17:03
id
is a built-in function that gives the identity of an object (which is also its memory address in CPython). If you name one of your functions id
, you will have to say builtins.id
to get the original (or __builtins__.id
in CPython). Renaming id
globally is confusing in anything but a small script.
However, reusing built-in names as variables isn't all that bad as long as the use is local. Python has a lot of built-in functions that (1) have common names and (2) you will not use much anyway. Using these as local variables or as members of an object is OK because it's obvious from context what you're doing:
Example:
def numbered(filename):
with open(filename) as file:
for i, input in enumerate(file):
print("%s:\t%s" % (i, input), end='')
Some built-ins with tempting names:
id
list
,dict
map
all
,any
complex
,int
dir
input
slice
sum
min
,max
object
file
(removed in Python 3.0)buffer
(removed in Python 3.0)

- 28,235
- 9
- 60
- 81

- 18,329
- 4
- 46
- 56
-
9[PEP 8](https://www.python.org/dev/peps/pep-0008/), which was updated 01-Aug-2013, now advises avoiding potential confusion by simply appending `_` to the variable name. Please see [my answer](http://stackoverflow.com/a/28091085/1497596). – DavidRR Jan 22 '15 at 14:28
-
2It's worth noting that the `id` function returning the memory address of an object is a CPython implementation detail. It's also worth noting that the the function is only required to return a different number for any two _extant_ objects. If an object is garbage collected, its id may be recycled. – Zac Crites Mar 27 '16 at 13:12
-
@Zac Thanks! I edited the answer to add that point about the memory address, and a link so people can read more. – wjandrea Jul 02 '20 at 01:52
-
1Just a note: in Python 3, `file` is no longer a builtin (though most syntax highlighters still treat it as such). – CrazyChucky Dec 01 '21 at 21:42
I might say something unpopular here: id()
is a rather specialized built-in function that is rarely used in business logic. Therefore I don't see a problem in using it as a variable name in a tight and well-written function, where it's clear that id doesn't mean the built-in function.

- 20,642
- 3
- 24
- 21
-
11I would still avoid it if at all possible though. Even if for no other reason than to not hear coworkers complain. :-) – Jason Baker Feb 02 '09 at 16:29
-
4I completely agree: naming a variable "id" in a small function (and thus scope) is harmless. Very few people use the `id` builtin anyway. That said it took me a while when a colleague overrode the `list` builtin with a local variable. So the general rule other people mention still makes sense. – silviot Aug 30 '12 at 13:42
-
1In response to: > id is a rather specialized built-in > function that is rarely used in > business logic. Therefore I don't see > a problem in using it as a variable > name in a tight and well-written > function, whre it's clear that id > doesn't mean the built-in function. While this is true, it's probably a good idea to be more specific with this variable name than simply "id". Lots of things have IDs (especially if you're working with a RDBMS), and as the second line of Tim Peters's *The Zen of Python* tells us: > Explicit is better than implicit. See the rest by running: `import this` – Ross Sep 17 '08 at 03:00
-
1IMHO one could do without `id` nearly everywhere (the only time I can imagine using it outside of [abusive cases](https://codegolf.stackexchange.com/a/28851/176) is indirectly when using the `x is y` identity operator, where Python basically does `id(x) == id(y)` for you (i.e. you don't need to call it...). I'd categorically ignore `id` as a builtin, and when you *do* need it in a module, make it super explicit and `import builtins` and call it as `builtins.id`. – Nick T Jun 23 '21 at 20:22
Others have mentioned that it's confusing, but I want to expand on why. Here's an example, based on a true story. Basically, I wrote a class that takes an id
parameter but then tried to use the builtin id
later.
class Employee:
def __init__(self, name, id):
"""Create employee, with their name and badge id."""
self.name = name
self.id = id
# ... lots more code, making you forget about the parameter names
print('Created', type(self).__name__, repr(name), 'at', hex(id(self)))
tay = Employee('Taylor Swift', 1985)
Expected output:
Created Employee 'Taylor Swift' at 0x7efde30ae910
Actual output:
Traceback (most recent call last):
File "company.py", line 9, in <module>
tay = Employee('Taylor Swift', 1985)
File "company.py", line 7, in __init__
print('Created', type(self).__name__, repr(name), 'at', hex(id(self)))
TypeError: 'int' object is not callable
Huh? Where am I trying to call an int? Those are all builtins...
If I had named it badge_id
or id_
, I wouldn't have had this problem.
Update: Thankfully, this part of the error is clearer in Python 3.11+:
print('Created', type(self).__name__, repr(name), 'at', hex(id(self)))
^^^^^^^^

- 28,235
- 9
- 60
- 81
It's bad to name any variable after a built in function. One of the reasons is because it can be confusing to a reader that doesn't know the name is overridden.

- 7,462
- 2
- 28
- 31
id
is a built-in function in Python. Assigning a value to id
will override the function. It is best to either add a prefix as in some_id
or use it in a different capitalization as in ID
.
The built in function takes a single argument and returns an integer for the memory address of the object that you passed (in CPython).
>>> id(1)
9787760
>>> x = 1
>>> id(x)
9787760

- 28,235
- 9
- 60
- 81

- 3,284
- 3
- 23
- 24
-
2note that you can name a class attribute or method 'id', that won't touch the built in function. – Toni Ruža Sep 16 '08 at 21:59
Because python is a dynamic language, it's not usually a good idea to give a variable and a function the same name. id() is a function in python, so it's recommend not to use a variable named id. Bearing that in mind, that applies to all functions that you might use... a variable shouldn't have the same name as a function.

- 1,624
- 2
- 11
- 7
-
3"Because python is a dynamic language, it's not usually a good idea to give a variable and a function the same name." -- You cannot give a variable and a function the same name. Nothing to do with it being a dynamic language. If you mean giving *properties* the same names as other objects in the same scope, I also disagree. You may have a class called "Key", an instance of that class called "key" and a property of another object called "key", e.g., "door.key". – Purrell Nov 01 '12 at 06:58