在Python中导入模块-最佳实践
我是Python新手,因为我想扩展我使用R。 在R中,我倾向于加载一堆库,有时会导致函数名冲突 Python中的最佳实践是什么。我看到了一些具体的变化,我看不出它们之间有什么区别在Python中导入模块-最佳实践,python,coding-style,workflow,python-import,Python,Coding Style,Workflow,Python Import,我是Python新手,因为我想扩展我使用R。 在R中,我倾向于加载一堆库,有时会导致函数名冲突 Python中的最佳实践是什么。我看到了一些具体的变化,我看不出它们之间有什么区别 导入熊猫,从熊猫导入*,以及从熊猫导入数据帧 前两者之间有什么区别?我应该只导入我需要的东西吗。 另外,对于那些制作小程序来处理数据和计算简单统计数据的人来说,最糟糕的后果是什么 更新 我找到了这个。它解释了一切。import pandas在pandas名称空间下导入pandas模块,因此您需要使用pandas.foo
导入熊猫
,从熊猫导入*
,以及从熊猫导入数据帧
前两者之间有什么区别?我应该只导入我需要的东西吗。
另外,对于那些制作小程序来处理数据和计算简单统计数据的人来说,最糟糕的后果是什么
更新
我找到了这个。它解释了一切。
import pandas
在pandas名称空间下导入pandas模块,因此您需要使用pandas.foo
调用pandas中的对象
from pandas import*
将pandas模块中的所有对象导入当前名称空间,因此您可以仅使用foo
调用pandas中的对象。请记住,如果当前名称空间和名称空间之间存在任何命名冲突,这可能会产生未预料到的后果
导入数据帧的与上面相同,但只将数据帧
(而不是所有内容)导入当前命名空间
在我看来,第一种通常是最佳实践,因为它可以在代码中很好地划分不同的模块。一般来说,最好进行显式导入。
例如:
或:
Python中的另一个选项是,当名称冲突时,将x作为y导入:
from pandas import DataFrame as PDataFrame
from bears import DataFrame as BDataFrame
frame1 = PDataFrame()
frame2 = BDataFrame()
它们都适用于不同的环境(这就是它们都可用的原因)。除了关于清晰性、可维护性和简单性的通用母性声明之外,没有深入的指导原则。我自己代码中的一些示例:
导入sys、os、re、itertools
避免了名称冲突,并提供了一种非常简洁的方法来导入一组标准模块
from math import*
允许我编写sin(x)
而不是math.sin(x)
数学重码。当我还导入numpy时,这有点冒险,它在其中一些函数上加倍,但我并不太担心,因为它们通常都是相同的函数。另外,我倾向于遵循numpy文档-将numpy导入为np
,这完全回避了这个问题
我喜欢来自PIL导入图像的,ImageDraw
,因为这是PIL文档展示其示例的方式
本质上等于以下三个陈述
import A
B = A.B
del A
就这样,就这样。每种形式的缺点
当阅读别人的代码时(这些人使用
不同的导入样式),我注意到
每种样式:
导入模块verylongname
将使代码更加混乱
使用长模块名(例如,concurrent.futures
或django.contrib.auth.backends
),并降低这些位置的可读性
从模块导入*
中,我没有机会从语法上看到,
例如,classA
和classB
来自同一模块和
彼此有很多关系。
这使得阅读代码变得困难。
(b)从该项进口
可能来自早期导入的阴影名称是该问题的最小部分。)
从模块导入classA、classB、functionC、constantD、functionE
名字太多,使我的短期记忆超载
我心里需要分配给模块
,以便
连贯地理解代码
导入模块作为mwvln的长名称有时不够
对我来说有助于记忆
适当的妥协
基于以上观察,我得出以下结论
我自己的代码中的样式:
如果模块名称较短,则首选导入模块
例如,标准库中的大多数包。
如果我需要使用中模块的名称,它也是首选样式
在我自己的模块中只有两三个位置;
那么,清晰胜过简洁()
导入longername as ln
几乎在所有应用程序中都是首选样式
其他情况。
例如,我可能将django.contrib.auth.backends导入为djcab
。
根据上述标准1的定义,将使用缩写
经常,因此足够容易记忆
根据
规则
从模块导入xx
有时仍会出现在我的代码中。
我使用它的情况下,即使是as
格式出现夸张,
最著名的例子是来自datetime导入datetime的
(但是如果我需要更多的元素,我将导入datetime作为dt
)。以下是来自
导入通常应在单独的行上,例如:
Yes: import os
import sys
No: import sys, os
但是可以
from subprocess import Popen, PIPE
导入始终放在文件的顶部,紧跟在任何模块注释和docstring之后,模块全局变量和常量之前。
- 导入应按以下顺序分组:
- 标准库导入
- 相关第三方进口
- 本地应用程序/库特定导入
您应该在每组导入之间放置一个空行
建议绝对进口
它们更具可读性,并且在导入系统出错时提供更好的错误消息,从而使调试更容易
import mypkg.sibling
from mypkg import sibling
from mypkg.sibling import example
或显式相对导入
from . import sibling
from .sibling import example
不应使用隐式相对导入,并在Python 3中删除
No: from ..grand_parent_package import uncle_package
通配符导入(import mypkg.sibling
from mypkg import sibling
from mypkg.sibling import example
from . import sibling
from .sibling import example
No: from ..grand_parent_package import uncle_package
>>> def doit1():
... import string
... string.lower('Python')
...
>>> import string
>>> def doit2():
... string.lower('Python')
...
>>> import timeit
>>> t = timeit.Timer(setup='from __main__ import doit1', stmt='doit1()')
>>> t.timeit()
11.479144930839539
>>> t = timeit.Timer(setup='from __main__ import doit2', stmt='doit2()')
>>> t.timeit()
4.6661689281463623