我试图从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中将函数和变量封装在Classes中是一种好的做法,还是应该使用全局函数/变量?
答案 0 :(得分:1)
啊,在Python中,这被视为循环导入错误 - 并且可能令人难以置信地令人沮丧。 elements
从context
导入,反之亦然。这可能在Java中使用魔术编译器技巧,但由于Python(大多数)被解释,这是不可能的*。
Java和Python之间另一个未说明的区别是Python类更接近具有特殊API的散列映射而不是适当的Java类。因此,在同一个Python模块中放置具有严格相互依赖性的类(例如您编写的类)是完全可以接受的。这将删除循环导入错误。
通常,您希望按依赖性级别组织库模块 - 这意味着,lib
文件夹的叶子不会从项目中的任何其他内容导入,并且随着您的进展更接近根,更多的进口被吸引。在您的能力范围内,您希望您的导入结构是树,而不是蜘蛛网(如果这有任何意义)。没有编译器,这是我在一个大型(数百万行)Python项目中找到的唯一方法来保持理智。
以上评论通常被认为是最佳做法,下一个建议是高度自以为是:
我建议围绕I / O边界构建可执行模块。构建紧密互连的Python对象结构以及通过引用传递的复杂继承结构变得非常诱人。虽然在中小规模上这提供了开发优势,但是在更大规模上,您失去了轻松集成并发性的能力,因为您已经取消了代码与传输层无关的能力。
编辑:好的,可以通过使用导入语句排序,使用__import__
方法等来破解导入框架并完成此操作。但是,如果您打算进行大型项目,则不应该这样做 - 它非常脆弱且难以向团队解释。看起来你对最佳实践更感兴趣,这就是我如何指导我的答案。对不起,如果不清楚的话。
答案 1 :(得分:0)
在context.py
文件中,您应该在def
之前添加__init__
,同时类方法也不会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()