【问题标题】:Are the python built-in methods available in an alternative namespace anywhere?python 内置方法是否可以在任何地方的替代命名空间中使用?
【发布时间】:2018-04-02 15:12:09
【问题描述】:

pythonbuilt-in 方法是否可以在某个包中引用?

让我解释一下。在我早期使用 python 时,我制作了一个类似于以下的 django 模型:

class MyModel(models.Model):
    first_name = models.CharField(max_length=100, null=True, blank=True)
    last_name = models.CharField(max_length=100, null=True, blank=True)
    property = models.ForeignKey("Property")

此后我需要为其添加一个属性。这给我留下了这个模型:

class MyModel(models.Model):
    first_name = models.CharField(max_length=100, null=True, blank=True)
    last_name = models.CharField(max_length=100, null=True, blank=True)
    property = models.ForeignKey("Property")

    @property
    def name(self):
        return "{} {}".format(first_name, last_name)

所以现在在运行时出现错误:TypeError: 'ForeignKey' object is not callable。发生这种情况是因为属性的 ForeignKey 已替换内置标识符属性。我希望能够做的是,而不是 @property 使用 @sys.property (或类似的东西)。

注意:我已经知道将 name 属性移到属性字段声明上方的解决方法。我不太关心这种特殊情况,因为我是引用 python 内置程序的替代位置的主要问题。

【问题讨论】:

  • 也许我不明白,但你不能把你的MyModel类重命名为property,比如_property或者what-have-you?
  • 不,但这并不意味着我的无关紧要。
  • 好的。我正在查看的类代表一个正在生产中的数据库表。现在将property 字段名称更改为其他名称是不切实际的。在 django 中还有其他解决方法,但我主要是好奇内置程序是否存在于某个名称空间中,而我的(诚然三心二意的)谷歌搜索没有出现任何结果。
  • 好的,我明白了,太糟糕了。 Python 的关键字和内置函数经常与人们想要使用的名称发生冲突,例如filelist。你所能做的就是尽量记住它们,从一开始就避免这些问题。命名空间有帮助,但几乎任何语言都会有一个全球性的(所以最好远离它)。即使您做对了所有事情,语言更改仍然会咬您一口(就像他们在 2.2 版中添加 property() 时一样)。

标签: python built-in


【解决方案1】:

如果您使用的是 Python 2,请使用 builtins__builtin__

def open():
    pass

import __builtin__

print open
print __builtin__.open

这给了你:

<function open at 0x011E8670>
<built-in function open>

【讨论】:

  • 如果你能输入所有这些下划线,你也可以使用import __builtin__ as builtin 等。
【解决方案2】:

Python 有一个 builtins 模块,其中存储了“真正全局”的东西——通常只是 the standard builtin functions and types。在 Python 2 中,它被命名为 __builtin__,但工作原理基本相同。

这个模块可以像任何其他模块一样被导入 - 但它也神奇地为每个其他模块提供内置名称(不会隐藏它们)。


如果您想知道它是如何工作的,builtins 文档会说:

作为一个实现细节,大多数模块都有名称__builtins__ 作为其全局变量的一部分。 __builtins__ 的值通常是此模块或此模块的 __dict__ 属性的值。由于这是一个实现细节,因此 Python 的替代实现可能不会使用它。

exec 说:

如果 globals 字典不包含键 __builtins__ 的值,则会在该键下插入对内置模块字典 builtins 的引用。这样,您可以通过将您自己的 __builtins__ 字典插入到全局变量中,然后再将其传递给 exec() 来控制执行代码可用的内置函数。

因此,至少在 CPython 中,当您评估 abs 时,它会在 globals()['abs'] 中查找,但在那里找不到,然后在 globals()['__builtins__'].__dict__['abs'] 中查找。

每当 Python(或者至少是 CPython)创建一个新的模块对象时,它的代码都会针对带有 empty __builtins__globals 执行,这意味着默认的 builtins 模块值会被填充,所以这样可行。而这个globals 是为模块中定义的函数和类而复制的(以及任何你用globals 显式执行的操作而不显式替换__builtins__),所以它也可以在函数和类中工作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-27
    • 1970-01-01
    • 2013-12-25
    • 1970-01-01
    • 1970-01-01
    • 2013-03-28
    • 1970-01-01
    • 2012-09-09
    相关资源
    最近更新 更多