精华内容
下载资源
问答
  • 出现的bug为ImportError: cannot import name ‘SQLAlchemy’,翻译过来为ImportError:无法导入名称’SQLAlchemy’ 。 仔细的看了一遍原来是 文件名和将要导入的包名重复了 这时只需要把python 文件名改成和包名不...

    代码如下

    这里是引用

    出现的bug为ImportError: cannot import name ‘SQLAlchemy’,翻译过来为ImportError:无法导入名称’SQLAlchemy’ 。

    仔细的看了一遍原来是 文件名和将要导入的包名重复了 这时只需要把python 文件名改成和包名不一样的就可以了,希望可以帮到大家。

    展开全文
  • 摄影:产品经理kingname 的第一套乐高对不少 Python 初学者来说,Python 导入其他模块的方式让他们很难理解。什么时候用import xxx?什么时候用from xxx ...

    摄影:产品经理

    kingname 的第一套乐高

    对不少 Python 初学者来说,Python 导入其他模块的方式让他们很难理解。什么时候用import xxx?什么时候用from xxx import yyy?什么时候用from xxx.yyy import zzz?什么时候用from xxx import *

    这篇文章,我们来彻底搞懂这个问题。

    系统自带的模块

    以正则表达式模块为例,我们经常这样写代码:

    import re
    
    target = 'abc1234xyz'
    re.search('(\d+)', target)
    

    但有时候,你可能会看到某些人这样写代码:

    from re import search
    target = 'abc1234xyz'
    search('(\d+)', target)
    

    那么这两种导入方式有什么区别呢?

    我们分别使用type函数来看看他们的类型:

    >>> import re
    >>> type(re)
    <class 'module'>
    >>> from re import search
    >>> type(search)
    <class 'function'>
    

    如下图所示:

    可以看到,直接使用import re导入的re它是一个module类,也就是模块。我们把它成为正则表达式模块。而当我们from re import search时,这个search是一个function类,我们称呼它为search 函数

    一个模块里面可以包含多个函数。

    如果在你的代码里面,你已经确定只使用search函数,不会再使用正则表达式里面的其他函数了,那么你使用两种方法都可以,没什么区别。

    但是,如果你要使用正则表达式下面的多个函数,或者是一些常量,那么用第一种方案会更加简洁清晰。

    例如:

    import re
    
    re.search('c(.*?)x', flags=re.S)
    re.sub('[a-zA-Z0-9]', '***', target, flags=re.I)
    

    在这个例子中,你分别使用了re.searchre.subre.Sre.I。后两者是常量,用于忽略换行符和大小写。

    但是,如果你使用from re import search, sub, S, I来写代码,那么代码就会变成这样:

    import re
    
    search('c(.*?)x', flags=S)
    sub('[a-zA-Z0-9]', '***', target, flags=I)
    

    看起来虽然简洁了,但是,一旦你的代码行数多了以后,你很容易忘记SI这两个变量是什么东西。而且我们自己定义的函数,也很有可能取名为sub或者search,从而覆盖正则表达式模块下面的这两个同名函数。这就会导致很多难以觉察的潜在 bug。

    再举一个例子。Python 的 datetime模块,我们可以直接import datetime,此时我们导入的是一个datetime模块,如下图所示:

    但是如果你写为from datetime import datetime,那么你导入的datetime是一个type类:

    因为这种方式导入的datetime,它就是Python 中的一种类型,用于表示包含日期和时间的数据。

    这两种导入方式导入的datetime,虽然名字一样,但是他们的意义完全不一样,请大家观察下面两种写法:

    import datetime
    
    now = datetime.datetime.now()
    one_hour_ago = now - datetime.timedelta(hours=1)
    
    from datetime import datetime, timedelta
    now = datetime.now()
    one_hour_ago = now - timedelta(hours=1)
    

    第二种写法看似简单,但实则改动起来却更为麻烦。例如我还需要增加一个变量today用于记录今日的日期。

    对于第一段代码,我们只需要增加一行即可:

    today = datetime.date.today()
    

    但对于第二行来说,我们需要首先修改导入部分的代码:

    from datetime import datetime, timedelta, date
    

    然后才能改代码:today = date.today()

    这样一来你就要修改两个地方,反倒增加了负担。

    第三方库

    在使用某些第三方库的代码里面,我们会看到类似这样的写法:

     from lxml.html import fromstring
     
     selector = fromstring(HTML)
    

    但是我们还可以写为:

    from lxml import html
    
    selector = html.fromstring(HTML)
    

    但是,下面这种写法会导致报错:

    import lxml
    selector = lxml.html.fromstring(HTML)
    

    那么这里的lxml.html又是什么东西呢?

    这种情况多常见于一些特别大型的第三方库中,这种库能处理多种类型的数据。例如lxml它既能处理xml的数据,又能处理html的数据,于是这种库会划分子模块,lxml.html模块专门负责html相关的数据。

    自己来实现多种导入方法

    我们现在自己来写代码,实现这多种导入方法。

    我们创建一个文件夹DocParser,在里面分别创建两个文件main.pyutil.py,他们的内容如下:

    util.py文件:

    def write():
        print('write 函数被调用!')
    

    main.py文件:

    import util
    
    util.write()
    

    运行效果如下图所示:

    现在我们把main.py的导入方式修改一下:

    from util import write
    
    write()
    

    依然正常运行,如下图所示

    当两个文件在同一个文件夹下面,并且该文件夹里面没有__init__.py 文件时,两种导入方式等价。

    现在,我们来创建一个文件夹microsoft,里面再添加一个文件parse.py

    def read():
        print('我是 microsoft 文件夹下面的 parse.py 中的 read函数')
    

    如下图所示:

    此时我们在 main.py中对它进行调用:

    from microsoft import parse
    
    parse.read()
    

    运行效果如下图所示:

    我们也可以用另一种方法:

    from microsoft.parse import read
    
    read()
    

    运行效果如下图所示:

    但是,你不能直接导入microsoft,如下图所示:

    你只能导入一个模块或者导入一个函数或者类,你不能导入一个文件夹

    无论你使用的是import xxx还是from xxx.yyy.zzz.www import qqq,你导入进来的东西,要不就是一个模块(对应到.py 文件的文件名),或者是某个.py 文件中的函数名、类名、变量名。

    无论是import xxx还是from xxx import yyy,你导入进来的都不能是一个文件夹的名字。

    可能有这样一种情况,就是某个函数名与文件的名字相同,例如:

    microsoft文件夹里面有一个microsoft.py文件,这个文件里面有一个函数叫做microsoft,那么你的代码可以写为:

    from microsoft import microsoft`
    microsoft.microsoft()
    

    但请注意分辨,这里你导入的还是模块,只不过microsoft.py文件名与它所在的文件夹名恰好相同而已。

    总结

    无论是使用import还是from import,第一个要求是代码能够正常运行,其次,根据代码维护性,团队编码风格来确定选择哪一种方案。

    如果我们只会使用到某个模块下面的一个函数(或者常量、类)并且名字不会产生混淆,可识别性高,那么from 模块名 import 函数名这没有什么问题。

    如果我们会用到一个模块下面的多个函数,或者是我们将要使用的函数名、常量名、类名可能会让人产生混淆(例如 re.S、re.I),那么这种情况下,import 模块名然后再 模块名.xxx来调用会让代码更加清晰,更好维护。

    但无论什么情况下,都禁止使用from xxx import *这种写法,它会给你带来无穷无尽的噩梦。

    未完待续

    在明天的文章中,我们来讲讲还有一种写法from . import xxx,以及当文件夹中存在__init__.py时,导入方式又有什么变化。

    近期热门:
    

    由菜鸟学Python原班人马打造的公众号【程序员GitHub】,专注于分享GitHub上有趣的资源包括,Python,Java,Go语言前端学习等优质的学习资源,爆料程序员圈的新鲜趣事,热门干货,职场感悟,感兴趣的小伙伴可以来捧场!

    程序员GitHub

    展开全文
  • Python 3.x | 史上最详解的 导入(import

    万次阅读 多人点赞 2018-07-27 15:05:02
    当然将moduleA.py语句 from moduleB import ClassB改为:import moduleB,将在第二次执行moduleB.py语句from moduleA import ClassA时报错:ImportError: cannot import name ‘classA’ 解决这种circular import...

    如需转载请注明出处。
    win10+Python 3.6.3

    一旦使用多层文件架构就很容易遇上import的坑!哈哈。

    一、理解一些基本概念

    1、模块、包
    **模块 module:**一般情况下,是一个以.py为后缀的文件。其他可作为module的文件类型还有".pyo"、".pyc"、".pyd"、".so"、".dll",但Python初学者几乎用不到。
    module 可看作一个工具类,可共用或者隐藏代码细节,将相关代码放置在一个module以便让代码更好用、易懂,让coder重点放在高层逻辑上。
    module能定义函数、类、变量,也能包含可执行的代码。module来源有3种:
    ①Python内置的模块(标准库);
    ②第三方模块;
    ③自定义模块。

    包 package: 为避免模块名冲突,Python引入了按目录组织模块的方法,称之为 包(package)。包 是含有Python模块的文件夹。
    这里写图片描述
    当一个文件夹下有   init   .py时,意为该文件夹是一个包(package),其下的多个模块(module)构成一个整体,而这些模块(module)都可通过同一个包(package)导入其他代码中。

    其中   init   .py文件 用于组织包(package),方便管理各个模块之间的引用、控制着包的导入行为。
    该文件可以什么内容都不写,即为空文件(为空时,仅仅用import [该包]形式 是什么也做不了的),存在即可,相当于一个标记。
    但若想使用from pacakge_1 import *这种形式的写法,需在  init  .py中加上:   all    = [‘file_a’, ‘file_b’] #package_1下有file_a.py和file_b.py,在导入时   init   .py文件将被执行。
    但不建议在   init   .py中写模块,以保证该文件简单。不过可在   init   .py导入我们需要的模块,以便避免一个个导入、方便使用。

    其中,   all   是一个重要的变量,用来指定此包(package)被import *时,哪些模块(module)会被import进【当前作用域中】。不在   all   列表中的模块不会被其他程序引用。可以重写  all  ,如   all    = [‘当前所属包模块1名字’, ‘模块1名字’],如果写了这个,则会按列表中的模块名进行导入。

    在模糊导入时,形如from package import *,*是由__all__定义的。

    精确导入,形如 from package import *、import package.class。

       path   也是一个常用变量,是个列表,默认情况下只有一个元素,即当前包(package)的路径。修改   path   可改变包(package)内的搜索路径。

    当我们在导入一个包(package)时(会先加载   init   .py定义的引入模块,然后再运行其他代码),实际上是导入的它的   init   .py文件(导入时,该文件自动运行,助我们一下导入该包中的多个模块)。我们可以在   init   .py中再导入其他的包(package)或模块 或自定义类。

    2、sys.modules、命名空间、模块内置属性
    2.1 sys.modules
    官方解释:链接
    sys.modules 是一个 将模块名称(module_name)映射到已加载的模块(modules) 的字典。可用来强制重新加载modules。Python一启动,它将被加载在内存中。
    当我们导入新modules,sys.modules将自动记录下该module;当第二次再导入该module时,Python将直接到字典中查找,加快运行速度。

    它是个字典,故拥有字典的一切方法,如sys.modules.keys()、sys.modules.values()、sys.modules[‘os’]。但请不要轻易替换字典、或从字典中删除某元素,将可能导致Python运行失败。

    import sys
    print(sys.modules)#打印,查看该字典具体内容。
    

    2.2 命名空间
    如同一个dict,key 是变量名字,value 是变量的值。

    • 每个函数function 有自己的命名空间,称local namespace,记录函数的变量。
    • 每个模块module 有自己的命名空间,称global namespace,记录模块的变量,包括functions、classes、导入的modules、module级别的变量和常量
    • build-in命名空间,它包含build-in function和exceptions,可被任意模块访问。

    某段Python代码访问 变量x 时,Python会所有的命名空间中查找该变量,顺序是:

    1. local namespace 即当前函数或类方法。若找到,则停止搜索;
    2. global namespace 即当前模块。若找到,则停止搜索;
    3. build-in namespace Python会假设变量x是build-in的函数函数或变量。若变量x不是build-in的内置函数或变量,Python将报错NameError。
    4. 对于闭包,若在local namespace找不到该变量,则下一个查找目标是父函数的local namespace。

    例:namespace_test.py代码

    def func(a=1):
    	b = 2
    	print(locals())#打印当前函数(方法)的局部命名空间
    	'''
    	locs = locals()#只读,不可写。将报错!
    	locs['c'] = 3
    	print(c)
    	'''
    	return a+b
    func()
    glos = globals()
    glos['d'] = 4
    print(d)
    
    print(globals())#打印当前模块namespace_test.py的全局命名空间
    

    内置函数locals()、globals()返回一个字典。区别:前者只读、后者可写。

    命名空间 在from module_name import 、import module_name中的体现:from关键词是导入模块或包中的某个部分。

    1. from module_A import X:会将该模块的函数/变量导入到当前模块的命名空间中,无须用module_A.X访问了。
    2. import module_A:modules_A本身被导入,但保存它原有的命名空间,故得用module_A.X方式访问其函数或变量。

    2.3 模块内置属性

    1.    name   直接运行本模块,   name   值为   main   ;import module,   name   值为模块名字。
    2.    file   当前 module的绝对路径
    3.    dict   
    4.    doc   
    5.    package   
    6.    path   

    3、绝对导入、相对导入
    这里写图片描述
    3.1 绝对导入:所有的模块import都从“根节点”开始。根节点的位置由sys.path中的路径决定,项目的根目录一般自动在sys.path中。如果希望程序能处处执行,需手动修改sys.path。
    例1:c.py中导入B包/B1子包/b1.py模块

    import sys,os
    BASE_DIR = os.path.dirname(os.path.abspath(__file__))#存放c.py所在的绝对路径
    
    sys.path.append(BASE_DIR)
    
    from B.B1 import b1#导入B包中子包B1中的模块b1
    

    例2:b1.py中导入b2.py模块

    from B.B1 import b2#从B包中的子包B1中导入模块b2
    

    3.2 相对导入:只关心相对自己当前目录的模块位置就好。不能在包(package)的内部直接执行(会报错)。不管根节点在哪儿,包内的模块相对位置都是正确的。
    b1.py代码

    #from . import b2 #这种导入方式会报错。
    import b2#正确
    b2.print_b2()
    

    b2.py代码

    def print_b2():
    	print('b2')
    

    运行b1.py,打印:b2。

    在使用相对导入时,可能遇到ValueError: Attempted relative import beyond toplevel package
    解决方案:参考这篇文章,链接

    3.3 单独导入包(package):单独import某个包名称时,不会导入该包中所包含的所有子模块。
    c.py导入同级目录B包的子包B1包的b2模块,执行b2模块的print_b2()方法:
    c.py代码

    import B
    B.B1.b2.print_b2()
    

    运行c.py,会报错。

    解决办法
    B/   init   .py代码

    from . import B1#其中的.表示当前目录
    

    B/B1/   init   .py代码

    from . import b2
    

    此时,执行c.py,成功打印:b2。

    3.4 额外
    ①一个.py文件调用另一个.py文件中的类。
    如 a.py(class A)、b.py(class B),a.py调用b.py中类B用:from b import B
    ②一个.py文件中的类 继承另一个.py文件中的类。如 a.py(class A)、b.py(class B),a.py中类A继承b.py类B。

    from b import B
    class A(B):
    pass
    

    二、Python运行机制:理解Python在执行import语句(导入内置(Python自个的)或第三方模块(已在sys.path中))时,进行了啥操作?

    step1:创建一个新的、空的module对象(它可能包含多个module);
    step2:将该module对象 插入sys.modules中;
    step3:装载module的代码(如果需要,需先编译);
    step4:执行新的module中对应的代码。

    在执行step3时,首先需找到module程序所在的位置,如导入的module名字为mod_1,则解释器得找到mod_1.py文件,搜索顺序是:
    当前路径(或当前目录指定sys.path)----->PYTHONPATH----->Python安装设置相关的默认路径。

    对于不在sys.path中,一定要避免用import导入 自定义包(package)的子模块(module),而要用from…import… 的绝对导入 或相对导入,且包(package)的相对导入只能用from形式。

    1、“标准”import,顶部导入
    这里写图片描述
    有上述基础知识,再理解这个思维导图,就很容易了。在运用模块的变量或函数时,就能得心应手了。

    2、嵌套import

    2.1 顺序导入-import
    这里写图片描述

    PS:各个模块的Local命名空间的独立的。即:
    test模块 import moduleA后,只能访问moduleA模块,不能访问moduleB模块。虽然moduleB已加载到内存中,如需访问,还得明确地在test模块 import moduleB。实际上打印locals(),字典中只有moduleA,没有moduleB。

    2.2 循环导入/嵌套导入-import
    这里写图片描述
    形如from moduleB import ClassB语句,根据Python内部import机制,执行细分步骤:

    1. 在sys.modules中查找 符号“moduleB”;
    2. 如果符号“moduleB”存在,则获得符号“moduleB”对应的module对象;
      从的   dict__中获得 符号“ClassB”对应的对象。如果“ClassB”不存在,则抛出异常“ImportError: cannot import name ‘classB’”
    3. 如果符号“moduleB”不存在,则创建一个新的 module对象。不过此时该新module对象的   dict   为空。然后执行moduleB.py文件中的语句,填充的   dict   

    总结:from moduleB import ClassB有两个过程,先from module,后import ClassB。
    这里写图片描述

    当然将moduleA.py语句 from moduleB import ClassB改为:import moduleB,将在第二次执行moduleB.py语句from moduleA import ClassA时报错:ImportError: cannot import name ‘classA’

    解决这种circular import循环导入的方法:
    例比:安装无线网卡时,需上网下载网卡驱动;
    安装压缩软件时,从网上下载的压缩软件安装程序是被压缩的文件。
    方法1----->延迟导入(lazy import):把import语句写在方法/函数里,将它的作用域限制在局部。(此法可能导致性能问题)
    方法2----->将from x import y改成import x.y形式
    方法3----->组织代码(重构代码):更改代码布局,可合并或分离竞争资源。
    合并----->都写到一个.py文件里;
    分离–>把需要import的资源提取到一个第三方.py文件中。
    总之,将循环变成单向。

    3、包(package)import
    在一个文件下同时有   init   .py文件、和其他模块文件时,该文件夹即看作一个包(package)。包的导入 和模块导入基本一致,只是导入包时,会执行这个   init   .py,而不是模块中的语句。
    而且,如果**只是单纯地导入包【形如:import xxx】**,而包的   init   .py中有没有明确地的其他初始化操作,则:此包下的模块 是不会被自动导入的。当然该包是会成功导入的,并将包名称放入当前.py的Local命名空间中。
    这里写图片描述
    [D:youcaihua\test\PkgDemo\mod.py]文件
    [D:youcaihua\test\PkgDemo\pkg1\pkg1_mod.py]文件
    [D:youcaihua\test\PkgDemo\pkg2\pkg2_mod.py]文件,三个文件同样的代码:

    def getName():
    	print(__name__)
    
    if __name__ == '__main__':
    	getName()
    

    [D:youcaihua\test\test.py]文件

    import PkgDemo.mod#1
    print(locals(),'\n')
    import PkgDemo.pkg1#2
    print(locals(),'\n')
    import PkgDemo.pkg1.pkg1_mod as m1#3
    print(locals(),'\n')
    import PkgDemo.pkg2.pkg2_mod#4
    PkgDemo.mod.getName()#5
    print('调用mod.py----', locals(), '\n')
    m1.getName()#6
    PkgDemo.pkg2.pkg2_mod.getName()#7
    

    执行 #1 后,将PkgDemo、PkgDemo.mod加入sys.modules中,此时可调用PkgDemo.mod的任何类、或函数。当不能调用包PkgDemo.pkg1或pkg2下任何模块。但当前test.py文件Local命名空间中只有 PkgDemo

    执行 #2 后,只是将PkgDemo.pkg1载入内存,sys.modules会有PkgDemo、PkgDemo.mod、PkgDemo.pkg1 三个模块。但PkgDemo.pkg1下的任何模块 都没有自动载入内存,所以在此时:PkgDemo.pkg1.pkg1_mod.getName()将会出错。当前test.py的Local命名空间依然只有PkgDemo。

    执行 #3 后,会将pkg1_mod载入内存,sys.modules会有PkgDemo、PkgDemo.mod、PkgDemo.pkg1、PkgDemo.pkg1.pkg1_mod四个模块,此时可执行PkgDemo.pkg1.pkg1_mod.getName()。由于使用了as,当前Local命名空间将另外添加m1(作为PkgDemo.pkg1.pkg1_mod的别名)、当然还有PkgDemo。

    执行 #4 后,会将PkgDemo.pkg2、PkgDemo.pkg2.pkg2_mod载入内存,sys.modules中会有PkgDemo、PkgDemo.mod、PkgDemo.pkg1、PkgDemo.pkg1.pkg1_mod、PkgDemo.pkg2、PkgDemo.pkg2.pkg2_mod六个模块,当然:当前Local命名空间还是只有PkgDemo、m1。

    #5#6#7当然都可正确执行。

    三、How to avoid Python circle import error?如何避免Python的循环导入问题?

    代码布局、(架构)设计问题,解决之道是:将循环变成单向。采用分层、用时导入、相对导入(层次建议不要超过两个)

    注意:在命令行执行Python xx.py、与IDE中执行,结果可能不同。

    如需转载请注明出处。
    参考:
    官方规范

    展开全文
  • 浅谈require和import

    万次阅读 多人点赞 2018-09-28 20:32:31
    最近在学习webpack时候,教程上用到的是require,但是之前我写代码用的Import比较多,所以借这个机会来学习一下: node编程中最重要的思想就是模块化,import和require都是被模块化所使用。 遵循规范 –require 是 ...

    最近在学习webpack时候,教程上用到的是require,但是之前我写代码用的Import比较多,所以借这个机会来学习一下:
    node编程中最重要的思想就是模块化,import和require都是被模块化所使用。

    遵循规范
    –require 是 AMD规范引入方式
    –import是es6的一个语法标准,如果要兼容浏览器的话必须转化成es5的语法

    调用时间
    –require是运行时调用,所以require理论上可以运用在代码的任何地方
    –import是编译时调用,所以必须放在文件开头

    本质
    –require是赋值过程,其实require的结果就是对象、数字、字符串、函数等,再把require的结果赋值给某个变量
    –import是解构过程,但是目前所有的引擎都还没有实现import,我们在node中使用babel支持ES6,也仅仅是将ES6转码为ES5再执行,import语法会被转码为require

    require时代的模块
    node编程中最重要的思想之一就是模块,而正是这个思想,让JavaScript的大规模工程成为可能。模块化编程在js界流行,也是基于此,随后在浏览器端,requirejs和seajs之类的工具包也出现了,可以说在对应规范下,require统治了ES6之前的所有模块化编程,即使现在,在ES6 module被完全实现之前,还是这样。

    node的module遵循CommonJS规范,requirejs遵循AMD,seajs遵循CMD,虽各有不同,但总之还是希望保持较为统一的代码风格。

    // -------- node -----------
    module.exports = {
      a : function() {},
      b : 'xxx'
    };
    // ----------- AMD or CMD ----------------
    define(function(require, exports, module){
      module.exports = {
        a : function() {},
        b : 'xxx'
      };
    });
    

    可以看出,为了保持风格的高度统一,除了在浏览器端的模块中要使用一个define函数来提供模块的闭包以外,其他代码可以完全一致。

    // b.js
    // ------------ node ---------
    var m = require('./a');
    m.a();
    // ------------ AMD or CMD -------------
    define(function(require, exports, module){
       var m = require('./a');
       m.a();
    });
    

    在使用上,也非常相似。

    ES6中的module
    ES6发布的module并没有直接采用CommonJS,甚至连require都没有采用,也就是说require仍然只是node的一个私有的全局方法,module.exports也只是node私有的一个全局变量属性,跟标准半毛钱关系都没有。

    export导出模块接口
    export的用法挺复杂的,具体有哪些可以看 这里 。这里举几个例子:

    // a.js
    export default function() {}
    export function a () {}
    
    var b = 'xxx';
    export {b}; // 这是ES6的写法,实际上就是{b:b}
    setTimeout(() => b = 'ooo', 1000);
    export var c = 100;
    

    在要导出的接口前面,加入export指令。
    在export之后,b还可以被修改,这和CommonJS有着巨大不同,关于内部机理的东西,本文就无耻的省略了。

    注意,下面的语法有严重错误:

    // 错误演示
    export 1; // 绝对不可以
    var a = 100;
    export a;
    

    export在导出接口的时候,必须与模块内部的变量具有一一对应的关系。直接导出1没有任何意义,也不可能在import的时候有一个变量与之对应。 export a 虽然看上去成立,但是 a 的值是一个数字,根本无法完成解构,因此必须写成 export {a} 的形式。即使a被赋值为一个function,也是不允许的。而且,大部分风格都建议,模块中最好在末尾用一个export导出所有的接口,例如:export {fun as default,a,b,c};
    import导入模块
    import的语法跟require不同,而且import必须放在文件的最开始,且前面不允许有其他逻辑代码,这和其他所有编程语言风格一致。

    import的使用和export一样,也挺复杂,可以在 这里 大致了解。举几个例子:

    import $ from 'jquery';
    import * as _ from '_';
    import {a,b,c} from './a';
    import {default as alias, a as a_a, b, c} from './a';
    

    这里有一些坑,下面会讲到。
    import后面跟上花括号的形式是最基本的用法,花括号里面的变量与export后面的变量一一对应。这里,你必须了解 对象的解构赋值 的知识,没这知识,你根本没法在这里装逼。了解了解构赋值,这里的“一一对应”的关系就能具体理解了。

    as关键字
    编程的同学对as都容易理解,简单的说就是取一个别名。export中可以用,import中其实可以用:

    // a.js
    var a = function() {};
    export {a as fun};
    
    // b.js
    import {fun as a} from './a';
    a();
    

    上面这段代码,export的时候,对外提供的接口是fun,它是a.js内部a这个函数的别名,但是在模块外面,认不到a,只能认到fun。

    import中的as就很简单,就是你在使用模块里面的方法的时候,给这个方法取一个别名,好在当前的文件里面使用。之所以是这样,是因为有的时候不同的两个模块可能通过相同的接口,比如有一个c.js也通过了fun这个接口:

    // c.js
    export function fun() {};
    

    如果在b.js中同时使用a和c这两个模块,就必须想办法解决接口重名的问题,as就解决了。

    default关键字
    其他人写教程什么的,都把default放到export那个部分,我觉得不利于理解。在export的时候,可能会用到default,说白了,它其实是别名的语法糖:

    // d.js
    export default function() {}
    // 等效于:
    function a() {};
    export {a as default};
    

    在import的时候,可以这样用:import a from './d';
    等效于,或者说就是下面这种写法的简写,是同一个意思
    import {default as a} from './d';
    这个语法糖的好处就是import的时候,可以省去花括号{}。简单的说,如果import的时候,你发现某个变量没有花括号括起来(没有*号),那么你在脑海中应该把它还原成有花括号的as语法。

    所以,下面这种写法你也应该理解了吧:

    import $,{each,map} from 'jquery';
    //import后面第一个 $ 是 {defalut as $} 的替代写法。
    

    *符号
    *就是代表所有,只用在import中,我们看下两个例子:

    import * as _ from '_';
    

    在意义上和import _ from '_'; 是不同的,虽然实际上后面的使用方法是一样的。它表示的是把’_’ 模块中的所有接口挂载到 _ 这个对象上,所以可以用 _.each 调用某个接口。

    另外还可以通过*号直接继承某一个模块的接口:

    export * from '_';
    // 等效于:
    import * as all from '_';
    export all;
    

    *符号尽可能少用,它实际上是使用所有export的接口,但是很有可能你的当前模块并不会用到所有接口,可能仅仅是一个,所以最好的建议是使用花括号,用一个加一个。

    该用require还是import?
    require的使用非常简单,它相当于module.exports的传送门,module.exports后面的内容是什么,require的结果就是什么,对象、数字、字符串、函数……再把require的结果赋值给某个变量,相当于把require和module.exports进行平行空间的位置重叠。

    而且require理论上可以运用在代码的任何地方,甚至不需要赋值给某个变量之后再使用,比如:

    require('./a')(); // a模块是一个函数,立即执行a模块函数
    var data = require('./a').data; // a模块导出的是一个对象
    var a = require('./a')[0]; // a模块导出的是一个数组
    

    你在使用时,完全可以忽略模块化这个概念来使用require,仅仅把它当做一个node内置的全局函数,它的参数甚至可以是表达式:require(process.cwd() + '/a');
    但是import则不同,它是编译时的(require是运行时的),它必须放在文件开头,而且使用格式也是确定的,不容置疑。它不会将整个模块运行后赋值给某个变量,而是只选择import的接口进行编译,这样在性能上比require好很多。

    从理解上,require是赋值过程,import是解构过程,当然,require也可以将结果解构赋值给一组变量,但是import在遇到default时,和require则完全不同: var $ = require('jquery');import $ from 'jquery'是完全不同的两种概念。

    上面完全没有回答“改用require还是import?”这个问题,因为这个问题就目前而言,根本没法回答,因为目前所有的引擎都还没有实现import,我们在node中使用babel支持ES6,也仅仅是将ES6转码为ES5再执行,import语法会被转码为require。这也是为什么在模块导出时使用module.exports,在引入模块时使用import仍然起效,因为本质上,import会被转码为require去执行。

    但是,我们要知道这样一个道理,ES7很快也会发布,js引擎们会尽快实现ES6标准的规定,如果一个引擎连标准都实现不了,就会被淘汰, ES6是迟早的事 。如果你现在仍然在代码中部署require,那么等到ES6被引擎支持时,你必须升级你的代码,而如果现在开始部署import,那么未来可能只需要做很少的改动。

    学习教程:https://www.tuicool.com/articles/uuUVBv2

    展开全文
  • @Import注解的作用

    万次阅读 多人点赞 2019-01-31 14:38:17
    } } 新建一个ImportConfig,在类上面加上@Configuration,加上@Configuration是为了能让Spring 扫描到这个类,并且直接通过@Import引入TestA类 @Import({TestA.class}) @Configuration public class ImportConfig { ...
  • java中import作用详解

    万次阅读 多人点赞 2017-07-07 17:47:19
    java中import详解import与package机制相关,这里先从package入手,再讲述import以及static import的作用。
  • python pandas numpy matplotlib 常用方法及...import numpy as np import pandas as pd import matplotlib.pyplot as plt ---------------numpy----------------------- arr = np.array([1,2,3], dtype
  • python中的import、from import以及import as的区别

    万次阅读 多人点赞 2019-07-02 22:18:48
    首先介绍一下import和include的区别或者说import相对include的好处: import导入的内容只会被包含一次,在引入之前会检测是否已经存在该模块,不存在才会被引入,而include是不会做判断的。使用import在递归包含的...
  • Go Import 整理关于 import 报错的分析及解决方法,希望通过此文可解决97%的import问题,3%可能与IDE有关。 1 import 过程理解: 首先明确 GOROOT 和 GOPATH 绝对路径,通过命令行go env即可查看。 包依赖引用的...
  • from sklearn.metrics import mean_squared_error File "D:\360Downloads\Python35\lib\site-packages\sklearn\__init__.py", line 82, in from .base import clone File "D:\360Downloads\Python35\lib\...
  • import os

    万次阅读 多人点赞 2019-07-25 15:31:52
    为什么要执行import os? import os的作用是什么? 1、为什么要执行import os? 我们在python下写程序,需要对文件以及文件夹或者其他的进行一系列的操作。但是,我们怎么在python中对文件进行操作呢?这就引入了os...
  • es6 import()函数

    万次阅读 多人点赞 2018-02-05 20:15:25
    import()函数 简介 前面介绍过,import命令会被 JavaScript 引擎静态分析,先于模块内的其他模块执行(叫做”连接“更合适)。所以,下面的代码会报错。 // 报错if (x === 2) { import MyModual from './...
  • 本地html文件中的script标签引入ES6的模块,直接在浏览器中打开该html文件,发现报错了:Uncaught SyntaxError: Cannot use import statement outside a module 对应的index.html: <!DOCTYPE html> <...
  • python中import的机制

    千次阅读 多人点赞 2017-09-30 08:31:19
    import XXX默认的就是在当前程序所在文件夹里init.py程序中导入XXX,如果当前程序所在文件夹里没有init.py文件的话,就不能这样写,而应该写成from .A import XXX,A是指当前文件夹下你想导入的函数(或者其他的)的...
  • Python中动态导入对象importlib.import_module()的使用

    万次阅读 多人点赞 2019-03-26 23:45:03
    目的就是提供Python中import语句的实现(以及__import__函数)。另外,importlib允许程序员创建他们自定义的对象,可用于引入过程(也称为importer)。 那么 imp 呢?还有一个 imp 模块提供了 import 语句接口,...
  • 详谈 import 路径

    千次阅读 2018-12-17 16:21:54
    import路径 import {test} from './test'; 花括号 import {test} from './test'; import test from './test'; 如果有默认导出export default则可以省略花括号,且import的模块名是随意的,如: // a.js export ...
  • import numpy as np 和 import pandas as pd

    千次阅读 2021-03-17 23:38:12
    import import()是python的一个内置函数,用于动态加载类和函数。 numpy NumPy(Numerical Python) 是 Python 语言的一个扩展程序库,支持大量的维度数组与矩阵运算,此外也针对数组运算提供大量的数学函数库。 通常...
  • 我之前已经在pytorch环境中安装了pytorch 和torchvision了,打开Anaconda prompt, 在python中可以import torch 和 torchvision,但是在pycharm中始终无法import. 后面寻找原因,发现了两个问题: 我的CUDA,
  • 一、import和from import的区别: import 只能导入模块、子包、包, 而不能导入模块中的类、函数、变量等 from import 可以导入模块、子包、包、类、函数、变量以及在包的__init__.py中已经导入的名字 ps: 但是两者都...
  • import sys

    千次阅读 2019-07-25 15:10:00
    import sys 的作用是什么? 参考来源 1、首先,先看一段代码 1. from sys import argv 2. script,first,second,third=argv 3. print ("The script is called: ",script) 4. print ("you first variable is: ",...
  • Python的from和import用法

    万次阅读 多人点赞 2019-06-22 11:01:38
    import使一个变量名引用整个模块对象,因此必须通过模块名称来得到该模块的属性,比如我们导入一个数学计算的模块 math: import math print math.pi #导出圆周率的值 >>>3.14159265359 我们导入math...
  • IDEA 如何自动导入(import

    万次阅读 2019-11-26 11:14:24
    如果大家正在使用一个未曾导入(import)过的类,或者它的静态方法或者静态字段,IDEA 会给出对应的建议,只要按下 ⌥(option)和回车就可以接受建议。 但我觉得这样做仍然很麻烦,不够智能化。怎么办呢? 打开 ...
  • Vue中import与@import的区别及使用场景

    千次阅读 2020-12-15 15:58:42
    import script中的import是js的语法, 是在js中去引用css文件 (ES6)模块化规范:默认导入语法 import 接收名称 from '模块标识符’ 使用 导入组件 import Vue from 'vue' 导入js、css、vue、less等文件 ...
  • import tkinter与from tkinter import *的区别

    千次阅读 2020-03-09 20:23:28
    from tkinter import * class DirList(object): def __init__(self,initdir=None): self.top= Tk() ##可以不加tkinter前缀 self.label = Label(self.top, text="Directory Lister V1.1") ##可以不加tki...
  • unused import statement

    千次阅读 2020-10-03 12:44:34
    import的内容被下面代码利用到了. ②pom.xml中写了依赖. 如果我们强行运行会出现这种报错: 可能的解决方案步骤 ①Project Structure设置好JDK ②src 右键mark as sources Directory ③File->...
  • 以前从来没有写过特别多的代码,这次在阅读论文的时候跑别人的代码的时候出现了很多import的问题,这里我想跟大家分享一下,我在Ubuntu系统,使用的是anaconda3,版本为3.6,我一般会在pycharm上跑代码,但是有时候...
  • python中import和from import的区别

    千次阅读 多人点赞 2018-08-31 10:46:02
    前些日子看到知乎上有人把import比作一辆车,把from import比作车子里面的矿泉水 我觉得这比喻还可以,但是首先得确定你是一个缺水的人,你渴你正要矿泉水,而不是什么咖啡牛奶 先举一个大家都清楚的例子: &...
  • java中指定importimport *的区别

    万次阅读 多人点赞 2018-08-16 13:11:05
    java中有两种包的导入机制,总结如下: ...单类型导入(single-type-import), 例如 import java.io.File; 按需类型导入(type-import-on-demand),例如 import java.io.*; 这里分析一下这两种导入...
  • Circular imports are fine where both modules use the “import ” form of import. They fail when the 2nd module wants to grab a name out of the first (“from module import name”) and the import is at ...
  • 前言: 作为一个中型的基于Spring的项目时,我们经常会分模块开发,那么bean定义文件我们如何分配和管理呢?是都放在一个配置文件中嘛?...import>标签 场景:我们目前的项目里已经有beans.xml配...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 6,323,641
精华内容 2,529,456
关键字:

import