【问题标题】:Naming conflict with built-in function与内置函数命名冲突
【发布时间】:2013-05-13 13:51:58
【问题描述】:

我犯了如下错误:

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

但是现在我想使用内置函数list()。如您所见,listname list 和内置函数list() 之间存在命名冲突。

如何在不重新启动 Python shell 的情况下将list 用作内置函数而不是变量?

【问题讨论】:

  • 好问题,每当人们使用内置名称时,我们都应该链接到这个
  • 值得注意:对您来说最好的办法可能是使用以下方法之一访问内置版本,并将list名称重新绑定到它,以撤消您的错误。 list = __builtins__.list

标签: python list built-in


【解决方案1】:

第一步:将列表重新绑定到不同的名称

lst = list

第二步:删除list变量

del list

第三步不要再这样做了


比起__builtins__.list,我更喜欢这个,因为它节省了输入,而且你还没有留下一个名为list 的变量。但是,最好完全避免这个问题。编写生产代码时,请始终记住不要将变量命名为与内置函数相同的名称。

【讨论】:

  • 这是一个很好的答案。除了你提到的优点外,它不依赖于 CPython 的实现细节!
  • 对不起,这是我书中的错误答案。 -1。这绝对是一种可能性,但它违背了我认为编码的敏感性。这会导致您的代码在任何地方都与其他 Python 脱节,任何查看代码段的人都会感到困惑,并且它与其他模块无法正常工作。换句话说,这会不断中断并且非常脆弱。
  • @InbarRose 这个问题特别适用于 Python 解释器外壳。在生产代码中使用这些答案中提供的任何技巧将是疯狂——我的意思是任何在实时解释器之外编写的代码。
  • How can I use list as a built-in function not a list variable without restart the Python shell? @InbarRose - 这可能是最容易在 shell 中键入的,并且还记得首先将现有变量重新绑定到其他东西......(不仅仅是得到list返回)
  • @InbarRose 您似乎没有考虑到问题的上下文。
【解决方案2】:

使用__builtins__.list__builtins__['__list__'](取决于上下文),或者干脆再次删除list (del list)。

无需导入:

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

__builtins__ 的存在是一个 CPython 实现细节;在__main__ 模块中它是一个模块,在其他任何地方它都是模块__dict__ 字典。 Jython、IronPython 和 PyPy 可能会选择根本不提供此功能。对于这些平台,请使用__builtin__ module,对于与 Python 3 兼容的实现,请使用builtins module

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

【讨论】:

  • 回复:__builtins__.list - 不要这样做。仅仅因为你可以并不意味着你应该。
  • @FogleBird 鉴于 OP 给出的情况 - 解释器出现错误,我认为这样做没有任何问题。显然,在文件中编写的任何代码中,情况都是不同的。
【解决方案3】:

不要使用内置函数或类型作为变量名。就这么简单,语言不是为此而生的。而且这样做毫无意义。

不仅如此 - 使用名称“列表”作为列表非常含糊,我怀疑它甚至可以在任何实际代码中远程使用。


您应该 永远隐藏内置的原因有几个。下面是一些比较严重的:

  • 兼容性,代码无法与其他模块一起使用。
  • 混乱,任何阅读您的代码的人都不会明白发生了什么。
  • 在某些情况下,许多内置程序使用其他内置程序,更改一个可能会对代码的其他方面产生意想不到的结果。

【讨论】:

  • 这没有回答问题 - OP 明白他所做的事情是错误的,但他正在使用 shell 并希望修复错误。
  • 在使用这些内置函数名作为变量名时,是否有某种方法可以使 Python 解释器发出警告和/或终止?与使用关键字作为变量名的情况一样吗?脚本中的一些初始命令使解释器更加挑剔?
【解决方案4】:

要修复错误,还有另一种选择——如果我们记得内置的“函数”list() 实际上是一个类,那么我们可以这样做:

list = type([])

【讨论】:

  • 那么当你覆盖type时你会怎么做呢?因为这正是我的情况:我有一个带有type 属性的类,我需要解决__init__ 中的歧义,同时仍然允许调用者调用,例如Transaction(type = Transaction.T_SINGLE)。我不能使用像_type 这样的不同名称,因为我正在实现一个API,而type 作为__init__ 的函数参数是面向用户的。你会认为在函数中删除 type 会像在全局范围内一样工作,但它会导致 python 在表面上错误 UnboundLocalError 上崩溃。
  • 所以我最终做的是在名为_typeof 的类中进行“备份”。我使用了名称_typeof,因此很明显其意图是类型检查(ala JavaScript);下划线是希望防止其他人将其与 JavaScript 的 typeof 运算符混淆。引用为Transaction._typeof(...)
  • @BradenBest 正确答案绝对是不要。如果你正在创建一个 API,那么调用 type 会用这个坏主意感染其他人的代码。如果它已经发货并且您必须保持兼容性,那么“备份”是一个非常好的策略。 Python 还提供了builtins 作为另一种取回它们的方法,但这通常比只执行您建议的操作开销更大(它在交互式 shell 中最有用)。
  • 啊,但是如果您使用的是python 2.x,则无法保证您可以使用它。 builtins 是一个 3.x 模块,用于解决 2.x 的 __builtins__,它是 Cpython 扩展而不是标准库的一部分。如果builtins 可以从__future__ 导入,这会很好,但是......是的。也就是说,我对解决方法不满意,所以我最终更改了函数签名__init__(self, price, [...], type) -> __init__(self, data),其中data 是一个字典。这(大部分)保留了 API,同时使与 JSON 的序列化变得简单。
【解决方案5】:

在 py2x 中使用__builtin__.list

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

不要使用__builtins__.list

来自docs

CPython 实现细节:用户不应触碰__builtins__;它 严格来说是一个实现细节。想要覆盖值的用户 在builtins 命名空间中应该导入__builtin__(没有's') 模块并适当修改其属性。

对于 py3x:

>>> import builtins
>>> builtins.list
<class 'list'>

【讨论】:

  • 不需要import,AFAIK。
  • __builtins__,不是__builtin__
  • @HenryKeiter:不,有一个__builtin__ module
  • @MartijnPieters 该模块需要导入(而__builtins__ 不需要)。该代码以一种或另一种方式无法按书面方式工作;它要么需要import __builtin__ 要么需要__builtins__.list
【解决方案6】:

它始终可用__builtins__.list:

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

如果你碰巧重新绑定那个,那么你就别无选择了。

您也可以在 Python 3 中使用模块 __builtin__(或 builtins,不带下划线),但您必须导入它。但这些是拼写同一事物的不同方式,而不是作为一个额外的选项 - 修改一个会影响两者:

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

【讨论】:

【解决方案7】:

是的,其他人在上面说,不要使用内置的名称作为变量名。这适用于listdict 等。

同样,正如其他人所说,您可以访问类型 list__builtins__.list。所以如果你需要拨打list,你还是可以找到的,只要你还没有反弹__builtins__.list

不过,重要的是,list 是一个名称。您已将其重新绑定到列表的一个实例。如果您想让list 再次表示&lt;type 'list'&gt;,只需重新绑定即可。在 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'>

【讨论】:

    猜你喜欢
    • 2016-05-03
    • 1970-01-01
    • 2020-04-23
    • 2015-02-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-04
    • 1970-01-01
    相关资源
    最近更新 更多