用Python导入模块 - 最佳实践

Joh*_*ohn 59 python workflow coding-style python-import

我是Python的新手,因为我想扩展我使用R学习的技能.在RI中,往往会加载一堆库,有时会导致函数名称冲突.

什么是Python的最佳实践.我看到一些具体的变化,我没有看到它们之间的区别

import pandas,from pandas import *from pandas import DataFrame

前两个之间有什么区别,我应该只输入我需要的东西.此外,对于制作小程序来处理数据和计算简单统计数据的人来说,最糟糕的后果是什么.

UPDATE

我找到了这个出色的指南.它解释了一切.

Pau*_*aul 44

import pandas在pandas命名空间下导入pandas模块,因此您需要使用pandas调用对象pandas.foo.

from pandas import *将pandas模块中的所有对象导入当前命名空间,因此您只能使用pandas调用对象foo.请记住,如果当前命名空间和pandas命名空间之间存在任何命名冲突,则可能会产生未预见的后果.

from pandas import DataFrame与上面相同,但只导入DataFrame(而不是所有)进入当前命名空间.

在我看来,第一个通常是最佳实践,因为它使不同的模块在代码中很好地划分.


Lut*_*elt 33

每种形式的缺点

当阅读其他人的代码(以及那些人使用非常不同的导入样式)时,我注意到每种样式存在以下问题:

import modulewithaverylongname将使用长模块名称(例如concurrent.futuresdjango.contrib.auth.backends)进一步混淆代码,并降低这些地方的可读性.

from module import *让我没有机会看到这句法,例如,classAclassB来自同一模块,并有大量的工作要做对方.它使得阅读代码变得困难.(来自此类导入的名称可能是早期导入的阴影名称是该问题的最小部分.)

from module import classA, classB, functionC, constantD, functionE 我的短期记忆超载我的心理需要分配的名称太多module,以便连贯地理解代码.

import modulewithaverylongname as mwvln我来说,有时候不足够的记忆.

一个合适的妥协

根据以上观察,我在自己的代码中开发了以下样式:

import module如果模块名称很短,则是首选样式,例如标准库中的大多数包.如果我需要在我自己的模块中只在两三个地方使用模块中的名称,它也是首选的样式; 清晰度胜过简洁("可读性计数").

import longername as ln几乎在所有其他情况下都是首选款式.例如,我可能会import django.contrib.auth.backends as dj_abe.根据上述标准1的定义,缩写将被频繁使用,因此足以容易记忆.

根据"明确比隐含更好",只有这两种风格完全是pythonic .规则.

from module import xx有时在我的代码中仍然会出现 我甚至在as格式夸张的情况下使用它,最着名的例子是from datetime import datetime.

  • **可爱的作品,鲁兹**。+1 个人资料 **“永恒原则”动机** - 在我们系统所基于的知识逐渐侵蚀和流沙的时代,这是真实且非常重要的。 (2认同)

Car*_*bés 23

一般来说,最好是进行显式导入.如:

import pandas
frame = pandas.DataFrame()
Run Code Online (Sandbox Code Playgroud)

要么:

from pandas import DataFrame
frame = DataFrame()
Run Code Online (Sandbox Code Playgroud)

Python中的另一个选项,当你有名称冲突时,导入x为y:

from pandas import DataFrame as PDataFrame
from bears import DataFrame as BDataFrame
frame1 = PDataFrame()
frame2 = BDataFrame()
Run Code Online (Sandbox Code Playgroud)


All*_*ітy 15

以下是PEP8样式指南的一些建议.

  1. 进口通常应分开,例如:

    Yes: import os
         import sys
    
    No:  import sys, os
    
    Run Code Online (Sandbox Code Playgroud)

    但是没关系

    from subprocess import Popen, PIPE
    
    Run Code Online (Sandbox Code Playgroud)
  2. 导入总是放在文件的顶部,就在任何模块注释和文档字符串之后,以及模块全局变量和常量之前.

    • 应按以下顺序对导入进行分组:
      1. 标准库导入
      2. 相关的第三方进口
      3. 本地应用程序/库特定导入
    • 您应该在每组导入之间添加一个空行.
  3. 建议使用绝对导入
    它们更易读,并且通过提供更好的错误消息来简化调试,以防您搞乱导入系统.

    import mypkg.sibling
    from mypkg import sibling
    from mypkg.sibling import example
    
    Run Code Online (Sandbox Code Playgroud)

    明确的相对进口

    from . import sibling
    from .sibling import example
    
    Run Code Online (Sandbox Code Playgroud)
  4. 永远不应该使用隐式相对导入,并在Python 3中删除.

    No:  from ..grand_parent_package import uncle_package
    
    Run Code Online (Sandbox Code Playgroud)
  5. from <module> import *应该避免使用通配符导入(),因为它们不清楚命名空间中存在哪些名称,使读者和许多自动化工具混淆.


关于一些建议lazy imports蟒速度性能的技巧.

进口报表开销

import语句几乎可以在任何地方执行.将它们置于函数内以限制其可见性和/或缩短初始启动时间通常很有用.尽管Python的解释器已经过优化,不能多次导入同一个模块,但在某些情况下,重复执行import语句会严重影响性能.

下面给出的是在页面上解释的场景,

>>> 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
Run Code Online (Sandbox Code Playgroud)


XuZ*_*ing 8

from A import B
Run Code Online (Sandbox Code Playgroud)

基本上等于以下三个陈述

import A
B = A.B
del A
Run Code Online (Sandbox Code Playgroud)

就是这样,就是这一切.

  • 这不完全正确.`from a import B`会将`A`导入全局命名空间,也导入`B`.如果你愿意,你仍然可以做"AC"(甚至是"AB"),但你也可以从itertools导入imap >>> itertools <module'itertools'(内置)> >>做`B`` > imap itertools.imap >>> itertools.starmap itertools.starmap` (4认同)