类/函数定义后的 Python 导入语句



我正在尝试从python模块导入函数。该函数是在我从中调用import的模块上声明的,但我仍在另一个文件上使用该函数。

这样:

context.py

from elements import *
class Context:
def __init__(self):
pass
@staticmethod
def load():
print "load code here"

elements.py

from context import *
class Item:
def __init__(self):
Context.load() # NameError: global name 'load' is not defined

作为来自 Java 的人,似乎应用相同的嵌套类访问逻辑在 Python 中不起作用。我想知道这里的最佳实践是什么,因为将import语句放在Context类下面似乎是不对的。我搜索了这个,但材料不清楚这种做法。

另外,在context.py我使用的是在elements定义的类的实例,反之亦然。所以我的问题实际上是这里最好的导入实践是什么。

另一个相关问题:在 Python 中的类中封装函数和变量是一种好习惯,还是应该改用全局函数/变量?

啊,在Python中,这被认为是一个循环导入错误 - 并且可能非常令人沮丧。elements是从context导入的,反之亦然。 这在Java中可能可以通过神奇的编译器技巧来实现,但由于Python(大部分)被解释,这是不可能的*。

Java和Python之间的另一个未说明的区别是,Python类比适当的Java类更接近具有特殊API的哈希映射。 因此,将具有紧密相互依赖关系的类(例如您编写的类)放在同一个 Python 模块中是完全可以接受和可取的。 这将消除循环导入错误。

通常,您希望按依赖级别组织模块 - 这意味着,lib文件夹的叶子不会从项目中的任何其他内容导入,并且随着您接近根目录,会绘制更多的导入。 尽你所能,你希望你的导入结构是一棵树,而不是一个蜘蛛网(如果这有任何意义的话)。 如果没有编译器,这是我在一个大型(数百万行)Python项目中发现的保持理智的唯一方法。

上述评论通常被认为是最佳实践,下一个建议非常固执己见:

我建议围绕 I/O 边界构建可执行模块。 使用通过引用传递的复杂继承结构构建紧密互连的 Python 对象结构变得非常诱人。 虽然在中小型上,这提供了开发优势,但在更大的规模上,您失去了轻松集成并发的能力,因为您已经剥夺了代码与传输层无关的能力。

编辑:好的,可以通过玩导入语句排序,使用__import__方法等来破解导入框架并完成此操作。 但是,如果您打算进行大型项目,则不应这样做 - 它非常脆弱且难以向团队解释。 似乎您对最佳实践更感兴趣,这就是我指导答案的方式。 对不起,如果不清楚。

context.py文件中,您应该在__init__之前添加def,类方法也不采用self

class Context:
def __init__(self):
pass
@staticmethod
def load():
print "load code here"

然后在另一个文件中:

from context import Context
class Item:
def __init__(self):
Context.load()

最新更新