'id'是Python中错误的变量名


141

为什么id在Python中命名变量很不好?


33
ID_,map_,list_,filter_等:大多数人下划线追加到与内建/关键字冲突的标识符
cdleary

3
一个更狡猾的解决方案将是使用一个变量ID
Simon Kuang

45
更好的问题是……哪个天才认为对内置函数使用这样的通用名称是个好主意?
2016年

Answers:


143

id() 是基本的内置功能:

帮助id模块中的 内置功能__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.)

通常,即使允许使用使用任何语言使关键字或内置函数都黯然失色的变量名也是一个坏主意。


3
好的,对于“ id”您是正确的,但是“一般...”注释仍然适用,您认为吗?
凯文·利特尔

5
对于模块全局变量,我肯定会避免使用它。对于限于局部范围的变量,您可以看到不再需要使用内置函数,这不是我担心的事情。
bobince

@Caramdir:好渔获物,id原定一次被移除,但最终他们决定不移除它。我不再能够编辑我的原始评论,因此将其删除以避免将来引起人们的混淆。
Eli Courtwright 2014年

19
@EliCourtwright我希望他们已将其删除。多么糟糕的方法!一个通用的通用名称,在数千个地方(上下文赋予含义)中使用。因此有人决定在没有上下文的情况下将其用作全局名称吗?
2016年

2
令人惊讶的是,Google自己的Python regex教程(developers.google.com/edu/python/regular-expressions)使用str = 'an example word:cat!!'。在任何PEP中是否有任何内容表明不执行此操作?
wordforthewise

57

PEP 8-Python代码样式指南中,以下指南出现在“ 描述性:命名样式 ”部分:

  • single_trailing_underscore_ :按惯例用于避免与Python关键字冲突,例如

    Tkinter.Toplevel(master, class_='ClassName')

因此,为了回答这个问题,应用此准则的示例是:

id_ = 42

在变量名中包括结尾的下划线可以使意图很清楚(对于那些熟悉PEP 8指南的人)。


1
这不回答实际问题,但一为PEP-8的命名约定
EGE

很好的建议,但id它是内置函数,而不是关键字,并且不能解释为什么隐藏内置函数不好。
wjandrea

51

id是一个内置函数,用于提供对象的标识(这也是CPython中的内存地址)。如果命名函数之一id,则必须说出builtins.id要获取的原始函数(或__builtins__.id在CPython中)。id全局重命名除了一个小脚本之外,其他任何地方都令人困惑。

但是,只要使用本地名称,将内置名称重用作为变量并没有什么坏处。Python具有许多内置函数,这些函数(1)具有通用名称,(2)无论如何都不会使用太多。可以将它们用作局部变量或作为对象的成员,因为从上下文可以明显看出您正在做什么:

例:

def numbered(filename):
    with open(filename) as file:
        for i, input in enumerate(file):
            print("%s:\t%s" % (i, input), end='')

一些带有诱人名称的内置函数:

  • id
  • file
  • listdict
  • map
  • allany
  • complexint
  • dir
  • input
  • slice
  • buffer
  • sum
  • minmax
  • object

8
PEP 8(已于2013年8月1日更新)现在建议通过简单地附加_到变量名来避免潜在的混乱。请看我的回答
DavidRR

1
值得注意的是,id返回对象内存地址的函数是CPython实现的细节。还值得注意的是,该函数仅需要为任意两个现存对象返回不同的数字。如果对象是垃圾回收,则其ID可能会被回收。
扎克·克里特

@扎克谢谢!我编辑了答案,以添加关于内存地址的那一点,以及一个链接,以便人们可以阅读更多内容。
wjandrea

42

我可能会在这里说一些不受欢迎的东西:这id()是一个相当专业的内置函数,很少在业务逻辑中使用。因此,在紧密且编写良好的函数中将其用作变量名时,我看不出有任何问题,在这种情况下,显然id并不意味着内置函数。


1
作为响应:> id是一个相当专门的内置>函数,很少在>业务逻辑中使用。因此,在使用紧密且编写良好的>函数中将其用作变量>名称时,我看不到任何问题,显然id>并不意味着内置函数。尽管这是事实,但最好使用此变量名而不是简单的“ id”来更具体。很多东西都有ID(特别是如果您正在使用RDBMS),正如Tim Peters的《 Python的禅宗》的第二行告诉我们的那样:>显式总比隐式好。跑步,看看其余内容:import this
罗斯

9
我仍然会尽可能避免它。即使没有其他原因,除了听不到同事的抱怨。:-)
杰森·贝克

1
我完全同意:在较小的函数中(因此在范围内)命名变量“ id”是无害的。id无论如何,很少有人使用内置函数。就是说,当我的同事list用局部变量覆盖了内置变量时,我花了一段时间。因此,其他人提到的一般规则仍然有意义。
silviot 2012年


2

id是Python中的内置函数。分配一个值id将覆盖该功能。最好在中添加前缀,some_id或在中使用不同的大小写形式ID

内置函数采用单个参数,并为您传递的对象(在CPython中)的内存地址返回一个整数。

>>> id(1)
9787760
>>> x = 1
>>> id(x)
9787760

2
请注意,您可以将类属性或方法命名为“ id”,而不会影响内置函数。
ToniRuža08年


0

其他人提到它令人困惑,但是我想进一步解释一下为什么。这是一个基于真实故事的示例。基本上,我编写了一个带有id参数的类,但是稍后尝试使用内置函数id

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)

预期产量:

Created Employee 'Taylor Swift' at 0x7efde30ae910

实际输出:

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

??我要在哪里叫int?这些都是内置的...

如果我将其命名为badge_idor id_,那么我就不会遇到这个问题。


-6

因为python是一种动态语言,所以给变量和函数起相同的名字通常不是一个好主意。id()是python中的函数,因此建议不要使用名为id的变量。请记住,这适用于您可能使用的所有函数...变量的名称不应与函数的名称相同。


3
“因为python是一种动态语言,所以给变量和函数起相同的名字通常不是一个好主意。” -您不能给变量和函数同名。与它是一种动态语言无关。如果您要赋予属性与相同范围内的其他对象相同的名称,我也不同意。您可能有一个名为“ Key”的类,该类的一个实例为“ key”,以及另一个名为“ key”的对象的属性,例如“ door.key”。
Purrell
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.