类/函数定义之后的Python import语句

时间:2018-04-11 14:59:32

标签: python class import module

我试图从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中是一种好的做法,还是应该使用全局函数/变量?

2 个答案:

答案 0 :(得分:1)

啊,在Python中,这被视为循环导入错误 - 并且可能令人难以置信地令人沮丧。 elementscontext导入,反之亦然。这可能在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()