Python(和 Django)最佳导入实践

发布于 2024-08-10 19:53:26 字数 801 浏览 3 评论 0原文

在导入代码的各种方法中,是否有一些方法比其他方法更适合使用?此链接http://effbot。简而言之 org/zone/import-confusion.htm 声明这

from foo.bar import MyClass

不是正常情况下导入 MyClass 的首选方法,或者除非您知道自己在做什么。相反,更好的方法是:

import foo.bar as foobaralias

然后在代码中访问 MyClass 使用

foobaralias.MyClass

简而言之,上面引用的链接似乎是说从模块导入所有内容通常更好,而不是而不仅仅是模块的一部分。

但是,我链接的那篇文章确实很旧。

我还听说,至少在 Django 项目的上下文中,最好只导入您想要使用的类,而不是整个模块。据说这种形式有助于避免循环导入错误或至少使 django 导入系统不那么脆弱。有人指出,Django 自己的代码似乎更喜欢“from x import y”而不是“import x”。

假设我正在处理的项目没有使用 __init__.py 的任何特殊功能...(我们所有的 __init__.py 文件都是空的),什么导入方法我应该赞成吗?为什么?

Out of the various ways to import code, are there some ways that are preferable to use, compared to others? This link http://effbot.org/zone/import-confusion.htm in short
states that

from foo.bar import MyClass

is not the preferred way to import MyClass under normal circumstances or unless you know what you are doing. Rather, a better way would like:

import foo.bar as foobaralias

and then in the code, to access MyClass use

foobaralias.MyClass

In short, it seems that the above-referenced link is saying it is usually better to import everything from a module, rather than just parts of the module.

However, that article I linked is really old.

I've also heard that it is better, at least in the context of Django projects, to instead only import the classes you want to use, rather than the whole module. It has been said that this form helps avoid circular import errors or at least makes the django import system less fragile. It was pointed out that Django's own code seems to prefer "from x import y" over "import x".

Assuming the project I am working on doesn't use any special features of __init__.py ... (all of our __init__.py files are empty), what import method should I favor, and why?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

自我难过 2024-08-17 19:53:26

第一个也是主要的导入规则:永远不要使用 from foo import *

本文讨论的是周期性导入的问题,该问题至今仍存在于结构不良的代码中。我不喜欢周期性进口;它们的存在是一个强烈的信号,表明某些模块做得太多,需要拆分。如果出于某种原因您需要使用无法重新安排的循环导入代码,import foo 是唯一的选择。

对于大多数情况,import foofrom foo import MyClass 之间没有太大区别。我更喜欢第二种,因为涉及的输入较少,但我可能使用第一种的原因有几个:

  • 模块和类/值具有不同的名称。当导入值的名称与模块无关时,读者可能很难记住特定导入来自何处。

    • 好:将 myapp.utils 导入为 utils; utils.frobnicate()
    • 好:将 myapp.utils 导入为 U; U.frobnicate()
    • 不好:from myapp.utils import frobnicate
  • 您正在从一个模块导入大量值。保护您的手指和读者的眼睛。

    • 不好:from myapp.utils import frobnicate, foo, bar, baz, MyClass, SomeOtherClass, # yada yada

First, and primary, rule of imports: never ever use from foo import *.

The article is discussing the issue of cyclical imports, which still exists today in poorly-structured code. I dislike cyclical imports; their presence is a strong sign that some module is doing too much, and needs to be split up. If for whatever reason you need to work with code with cyclical imports which cannot be re-arranged, import foo is the only option.

For most cases, there's not much difference between import foo and from foo import MyClass. I prefer the second, because there's less typing involved, but there's a few reasons why I might use the first:

  • The module and class/value have different names. It can be difficult for readers to remember where a particular import is coming from, when the imported value's name is unrelated to the module.

    • Good: import myapp.utils as utils; utils.frobnicate()
    • Good: import myapp.utils as U; U.frobnicate()
    • Bad: from myapp.utils import frobnicate
  • You're importing a lot of values from one module. Save your fingers, and reader's eyes.

    • Bad: from myapp.utils import frobnicate, foo, bar, baz, MyClass, SomeOtherClass, # yada yada
两人的回忆 2024-08-17 19:53:26

对我来说,这取决于具体情况。如果它是一个唯一命名的方法/类(即不是 process() 或类似的东西),并且您将经常使用它,那么请保存输入并只需执行 from foo import MyClass 即可。

如果您要从一个模块导入多个内容,最好只导入该模块,然后执行 module.bar、module.foo、module.baz 等,以保持命名空间干净。

你还说

据说这种形式有助于避免循环导入错误,或者至少使 django 导入系统不那么脆弱。有人指出,Django 自己的代码似乎更喜欢“from x import y”而不是“import x”。

我不知道其中一种方式如何有助于防止循环导入。原因是,即使您执行 from x import y,也会导入所有 x。只有 y 被带入当前命名空间,但整个模块 x 都会被处理。试试这个例子:

在 test.py 中,输入以下内容:

def a():
    print "a"

print "hi"

def b():
    print "b"

print "bye"

然后在 'runme.py' 中,输入:

from test import b

b()

然后只需执行 python runme.py

您将看到以下输出:

hi
bye
b

所以测试中的所有内容.py 已运行,即使您只导入了 b

For me, it's dependent on the situation. If it's a uniquely named method/class (i.e., not process() or something like that), and you're going to use it a lot, then save typing and just do from foo import MyClass.

If you're importing multiple things from one module, it's probably better to just import the module, and do module.bar, module.foo, module.baz, etc., to keep the namespace clean.

You also said

It has been said that this form helps avoid circular import errors or at least makes the django import system less fragile. It was pointed out that Django's own code seems to prefer "from x import y" over "import x".

I don't see how one way or the other would help prevent circular imports. The reason is that even when you do from x import y, ALL of x is imported. Only y is brought into the current namespace, but the entire module x is processed. Try out this example:

In test.py, put the following:

def a():
    print "a"

print "hi"

def b():
    print "b"

print "bye"

Then in 'runme.py', put:

from test import b

b()

Then just do python runme.py

You'll see the following output:

hi
bye
b

So everything in test.py was run, even though you only imported b

じ违心 2024-08-17 19:53:26

后者的优点是MyClass的起源更加明确。前者将 MyClass 放在当前命名空间中,以便代码可以不合格地使用 MyClass。因此,对于阅读定义 MyClass 的代码的人来说,这不太明显。

The advantage of the latter is that the origin of MyClass is more explicit. The former puts MyClass in the current namespace so the code can just use MyClass unqualified. So it's less obvious to someone reading the code where MyClass is defined.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文