2015-06-30 12 views
12

我正在读一些代码,看起来基本上是这样的:确保在创建类时定义“__module__”?

class Foo(object): 
    class_name = __module__.replace('_', '-') 

对我来说,这看起来很奇怪(__module__,那是什么?),所以我就去看了看蟒蛇data-model。快速搜索显示__module__是类对象和函数对象的属性。但是,在全局名称空间中没有可用的__module__(可以通过试图查看它并观察结果...)轻松验证。

我决定把这个做到特定的实现行为,但作为最后一个检查,我决定用其他的实现来测试我的方便。事实证明,此代码

  • CPython的2.7.6
  • CPython的执行3.4.0
  • 的jython 2.5.3
  • PyPy 2.2.1(Python的2.7.3)

我的问题是这种行为是否实际上在语言参考的任何地方定义。我不知道为什么我想要,但是我可以安全地依靠__module__在类创建命名空间中还是所有的实现者都决定以同样的方式做到这一点?

所有的Linux,但我怀疑的事项...

+1

除[Python 2.3 *新功能*](https://docs.python.org/2/whatsnew/2.3.html#build-and-c-api-changes)状态外,找不到任何内容* If您在扩展中动态分配类型对象时,应该注意与__module__和__name__属性有关的规则的更改。总之,你需要确保类型的字典包含一个'__module __''键;使模块名称成为类型名称的一部分直到最后一段时间将不再具有预期的效果。有关更多详细信息,请阅读API参考文档或来源。* –

+0

由于每个人似乎都支持这一点,因此要求将其标准化可能是合理的。 – Veedrac

+0

@Veedrac - 我其实不同意这里。在python中,名称只显示在你的(非全局)命名空间中是非常奇怪的。例如当我创建一个函数时,我不希望有任何神奇的名字出现... – mgilson

回答

8

什么文件确实定义是类将有一个__module__属性。 CPython看起来好像是在类块的开头定义了一个局部变量__module__。然后这个变量就像在那里定义的任何其他变量一样成为一个类属性。

我找不到任何文件说__module__必须以这种方式定义。特别是,我无法找到任何明确指出该属性必须在类体中定义为局部变量的文档,而不是在类创建的稍后阶段将其指定为类属性。 This answer不同的问题提到它以这种方式工作,并显示它是如何出现在字节码中的。有a Jython bug,他们通过使它与CPython相同来修复它们。

我猜这是一个CPython的实现细节,被转移到其他实现。据我所知,文档实际上并没有说__module__必须在类体内可用,只能在类对象之后。

+1

没错;名称首先在类体中创建的不保证语言“规范”中的任何地方。 –

+0

这也是我的想法。因此,我建议代码的初始作者依靠全局'__file__'(和'os'中的各种实用程序)来代替 - 尽管我想我可以告诉他们使用'__name__' ... – mgilson