在python中,如果您需要来自不同包的模块,则必须导入它.来自Java背景,这是有道理的.
import foo.bar
Run Code Online (Sandbox Code Playgroud)
什么是没有意义的,为什么每当我想使用酒吧时我需要使用全名?如果我想使用全名,为什么我需要导入?不使用全名立即描述我正在寻址的模块?
from foo import bar当这import foo.bar应该做什么时,似乎有点多余.当我打算使用全名时,为什么我必须导入也有点模糊.
Dav*_*d Z 23
问题是,即使Python的import声明看起来与Java类似,它们也会完全不同.如您所知,在Java中,import语句实际上只是对编译器的一个提示.它基本上为完全限定的类名设置别名.例如,当你写作
import java.util.Set;
Run Code Online (Sandbox Code Playgroud)
它告诉编译器,在整个文件中,当你写的时候Set,你的意思是java.util.Set.并且如果写s.add(o)在那里s是类型的对象Set,则编译器(或更确切地说,接头)熄灭并发现add方法中Set.class和在它的一个引用提出.
但在Python中,
import util.set
Run Code Online (Sandbox Code Playgroud)
(顺便说一下,这是一个制作模块)做了一些完全不同的事情.看看,在Python中,包和模块不仅仅是名称,它们是实际的对象,当您util.set在代码中编写时,它指示Python访问一个名为的对象util并在其上查找名为的属性set.Python import声明的工作是创建该对象和属性.它的工作方式是解释器查找名为的文件util/__init__.py,使用其中的代码定义对象的属性,并将该对象绑定到名称util.类似地,代码util/set.py用于初始化绑定的对象util.set.有一个函数调用__import__它来处理所有这些,事实上是声明import util.set 基本上相当于
util = __import__('util.set')
Run Code Online (Sandbox Code Playgroud)
关键是,当您导入Python模块时,您得到的是与顶级包对应的对象util.为了获得访问util.set你需要去通过,这就是为什么它似乎像你需要在Python中使用完全合格的名称.
当然,有办法解决这个问题.由于所有这些都是对象,一种简单的方法是绑定util.set到一个更简单的名称,即在import语句之后,你可以拥有
set = util.set
Run Code Online (Sandbox Code Playgroud)
从那时起你就可以使用set你本来写过的地方了util.set.(当然这会掩盖内置set类,所以我不建议实际使用该名称set.)或者,至少在另一个答案中提到,你可以写
from util import set
Run Code Online (Sandbox Code Playgroud)
要么
import util.set as set
Run Code Online (Sandbox Code Playgroud)
这仍然导入封装util与模块set中,但不是创建一个变量util在当前范围内,它会创建一个变量set引用util.set.在幕后,这有点像
_util = __import__('util', fromlist='set')
set = _util.set
del _util
Run Code Online (Sandbox Code Playgroud)
在前一种情况下,或
_util = __import__('util.set')
set = _util.set
del _util
Run Code Online (Sandbox Code Playgroud)
在后者中(尽管两种方式基本上都是一样的).这种形式在语义上更像Java的import声明所做的:它将别名(set)定义为通常只能由完全限定名称(util.set)访问的内容.
如果您愿意,可以缩短它:
import foo.bar as whateveriwant
Run Code Online (Sandbox Code Playgroud)
使用全名可防止具有相同名称子模块的两个包相互冲突.
| 归档时间: |
|
| 查看次数: |
899 次 |
| 最近记录: |