在Python中导入模块的最优雅方式是什么?

12 投票
4 回答
6000 浏览
提问于 2025-04-16 19:42

有没有人能告诉我,在Python中导入模块的最“Python风格”的方法是什么?让我来解释一下——我看过很多Python代码,发现有几种不同的导入模块的方法,或者更准确地说,是在什么情况下导入:

  1. 使用一个模块或几个模块,这些模块包含了整个项目所需的所有导入(第三方模块),这样所有的导入都集中在少数几个模块里,方便管理。当某个模块需要导入其他模块时,它会向“参考”模块请求。例如,在我们的项目中,有一个叫做“references”的层,里面包含了像“system.py”(包含所有系统库的引用)、“platform.py”(包含所有平台库的引用)、“devexpress.py”(包含所有devexpress库的引用)等模块。这些模块看起来是这样的:
  2. 每个模块在顶部导入所有必要的类和函数——例如,每个模块里都有一个导入的部分。
  3. 每个函数或类在定义后会局部使用导入,也就是说只导入它们真正需要的东西。

请看下面的示例。

1. 示例导入模块 - 只有'import'和'from ... import ...'语句(没有任何方法或类):

#references.py
import re
import clr
import math

import System
import System.Text.RegularExpressions
import System.Random
import System.Threading
import System.DateTime

# System assemblies

clr.AddReference("System.Core")
clr.AddReference("System.Data")
clr.AddReference("System.Drawing")
...

#test.py
from references.syslibs import (Array, DataTable, OleDbConnection, OleDbDataAdapter,
                                 OleDbCommand, OleDbSchemaGuid)

def get_dict_from_data_table(dataTable):
    pass

2. 模块包含'import'和'from ... import ...'以及方法和类:

from ... import ...
from ... import ...

def Generate(param, param1 ...):
    pass

3. 模块包含'import'和'from ... import ...'语句,这些语句在方法和类内部使用:

import clr
clr.AddReference("assembly")       

from ... import ...
...

def generate_(txt, param1, param2):
  from ... import ...
  from ... import ...
  from ... import ...

  if not cond(param1): res = "text"
  if not cond(param2): name = "default"

那么,在Python中导入模块的最“Python风格”的方法是什么呢?

4 个回答

3

在Python中,"import"这个命令会把一个模块加载到自己的命名空间里。这意味着,当你想使用这个模块里的东西时,必须在前面加上模块的名字和一个点,比如说模块名.函数名。

import animals
animals.Elephant()

而"from"这个命令则是把一个模块加载到当前的命名空间里,这样你就可以直接使用模块里的东西,而不需要再提模块的名字。

from animals import Elephant
Elephant()

或者

from animals import *
Elephant()

使用"from"是不错的选择,但如果你用通配符导入(也就是用*号导入所有内容),就不太推荐了。如果你的项目很大,导入来自不同模块的内容可能会导致名字冲突。比如说,如果你从两个不同的模块里都导入了Elephant()这个函数,就会出现问题(就像用通配符导入*一样)。

所以,如果你的项目比较大,导入了很多来自不同模块的内容,最好还是用"import",并且在使用时加上模块名.类名或函数名。否则,就可以用"from"的方式来导入...

6

大家已经对代码风格的问题(比如脚本开头的部分)进行了评论,所以我就不再重复了。

对于我的导入部分,我通常会按模块名称的字母顺序排列(无论是用'import'还是'from ... import ...')。我会把它们分成几个组:标准库;第三方模块(来自pypi或其他地方);内部模块。

import os
import system

import twisted
import zope

import mymodule_1
import mymodule_2
17

其实这真的没什么大不了的,只要你不使用 from ... import * 这种写法就行。其他的都是个人喜好,以及如何解决循环导入的问题。PEP 8 说你应该把导入放在脚本的最上面,但这也不是绝对的。

撰写回答