简体   繁体   English

有人可以解释这种意外的Python导入行为吗?

[英]Can someone explain this unexpected Python import behavior?

I've run into some behavior from Python 2.6.1 that I didn't expect. 我遇到了Python 2.6.1出乎意料的行为。 Here is some trivial code to reproduce the problem: 这里是一些简单的代码来重现该问题:

---- ControlPointValue.py ------
class ControlPointValue:
   def __init__(self):
      pass

---- ControlPointValueSet.py ----
import ControlPointValue

---- main.py --------------------
from ControlPointValue import *
from ControlPointValueSet import *

val = ControlPointValue()

.... here is the error I get when I run main.py (under OS/X Snow Leopard, if it matters): ....这是我运行main.py时遇到的错误(如果重要,在OS / X Snow Leopard下):

jeremy-friesners-mac-pro-3:~ jaf$ python main.py 
Traceback (most recent call last):
  File "main.py", line 4, in <module>
    val = ControlPointValue()
TypeError: 'module' object is not callable

Can someone explain what is going on here? 有人可以解释这里发生了什么吗? Is Python getting confused because the class name is the same as the file name? Python会因为类名与文件名相同而感到困惑吗? If so, what is the best way to fix the problem? 如果是这样,解决问题的最佳方法是什么? (I'd prefer to have my python files named after the classes that are defined in them) (我更喜欢以它们中定义的类命名的python文件)

Thanks, Jeremy 谢谢,杰里米

I don't think it's unexpected. 我不认为这是意外的。 What you are basically doing is: 您基本上在做什么是:

1) the first import in main.py imports the contents of ControlPointValue module into the global namespace. 1)main.py中的第一次导入将ControlPointValue模块的内容导入到全局名称空间中。 this produces a class bound to that name. 这将产生一个与该名称绑定的类。

2) the second import in main.py imports the contents of ControlPointValueSet module into the global namespace. 2)main.py中的第二次导入将ControlPointValueSet模块的内容导入到全局名称空间中。 This module imports ControlPointValue module. 此模块导入ControlPointValue模块。 This overwrites the binding in the global namespace, replacing the binding for that name from the class to the module. 这将覆盖全局名称空间中的绑定,从而将该名称的绑定从类替换为模块。

To solve, I would suggest you not to import *, ever. 为了解决这个问题,我建议您永远不要导入*。 Always keep the last module prefix. 始终保留最后一个模块前缀。 For example, if you have foo/bar/baz/bruf.py containing a class Frobniz, do 例如,如果您的foo / bar / baz / bruf.py包含Frobniz类,请执行

from foo.bar.baz import bruf

and then use bruf.Frobniz() 然后使用bruf.Frobniz()

In addition to the other suggestions about star imports, don't name your module and your class the same. 除了关于星号导入的其他建议外,不要将模块和类命名为相同的名称。 Follow pep8's suggestions and give your modules short all lower case names and name your classes LikeThis. 遵循pep8的建议,并为模块提供所有小写字母缩写,并将类命名为LikeThis。 Eg 例如

---- controlpoints.py ------
class ControlPointValue:
   def __init__(self):
      pass

---- valuesets.py ----
from controlpoints import ControlPointValue

---- main.py --------------------
from controlpoints import ControlPointValue
from valuesets import *

val = ControlPointValue()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM