我实际上已经尝试了解大约一年的Python导入,而且我已经放弃了Python中的编程,因为它似乎太混淆了。我来自C背景,我认为import
的工作方式与#include
类似,但如果我尝试导入某些东西,我总会得到错误。
如果我有两个这样的文件:
foo.py:
a = 1
bar.py:
import foo
print foo.a
input()
为什么我需要引用模块名称?为什么不能写import foo
,print a
?这种困惑有什么意义?为什么不运行代码并为您定义的东西就像在一个大文件中编写它一样?为什么它不能像C的#include指令一样工作,它基本上复制和粘贴你的代码?我在C中没有导入问题。
答案 0 :(得分:9)
要做你想做的事,你可以使用(不推荐,进一步阅读以解释):
from foo import *
这会将所有内容导入您当前的命名空间,您可以调用print a
。
然而,这种方法的问题如下。考虑具有两个模块moduleA
和moduleB
的情况,每个模块都有一个名为GetSomeValue()
的函数。
当你这样做时:
from moduleA import *
from moduleB import *
您有名称空间解析问题*,因为您实际使用GetSomeValue()
,moduleA.GetSomeValue()
或moduleB.GetSomeValue()
调用了什么功能?
除此之外,您还可以使用Import As
功能:
from moduleA import GetSomeValue as AGetSomeValue
from moduleB import GetSomeValue as BGetSomeValue
或者
import moduleA.GetSomeValue as AGetSomeValue
import moduleB.GetSomeValue as BGetSomeValue
此方法可手动解决冲突。
我相信您可以从这些示例中了解显式引用的必要性。
* Python有其命名空间解析机制,这只是为了解释的简化。
答案 1 :(得分:2)
想象一下,你的模块中有一个函数可以从列表中选择一些对象:
def choice(somelist):
...
现在想象一下,无论是在该函数中还是在模块的其他位置,您都在使用randint
库中的random
:
a = randint(1, x)
因此我们
import random
您建议,这会执行from random import *
现在访问的内容,这意味着我们现在有两个不同的函数,名为choice ,因为random
也包含一个。只有一个可以访问,但是您已经引入了关于代码中其他地方choice()
实际引用的内容的歧义。
这就是为什么导入一切都是不好的做法;导入你需要的东西:
from random import randint
...
a = randint(1, x)
或整个模块:
import random
...
a = random.randint(1, x)
这有两个好处:
答案 2 :(得分:1)
有几个很好的理由。该模块为其中的对象提供了一种命名空间,允许您使用简单的名称而不用担心冲突 - 来自C背景,您肯定会看到具有长而丑陋的函数名称的库,以避免与其他任何人发生冲突。 / p>
此外,模块本身也是对象。当在python程序中的多个位置导入模块时,每个模块实际上都获得相同的引用。这样,更改foo.a
会为每个人更改它,而不仅仅是本地模块。这与C相反,其中包含标题基本上是对源文件的复制+粘贴操作(显然你仍然可以共享变量,但机制有点不同)。
如前所述,您可以说from foo import *
或更好from foo import a
,但要了解基础行为实际上是不同的,因为您正在使用a
并将其绑定到本地模块。< / p>
如果您经常使用某些内容,则可以始终使用from
语法直接导入它,或者您可以将模块重命名为更短的内容,例如
import itertools as it
答案 3 :(得分:0)
执行import foo
时,会在名为module
的当前命名空间内创建新的foo
。
所以,要在foo中使用任何东西;你必须通过模块解决它。
但是,如果您使用from foo import something
,则无法使用前置模块名称,因为它将从模块加载something
并为其分配名称{{1 }}。 (不推荐做法)
答案 4 :(得分:0)
Option Explicit
Private WithEvents moTextDate As MSForms.TextBox
Public Property Set DateTextBox(ByVal oTxtBox As MSForms.TextBox)
Set moTextDate = oTxtBox
End Property
Private Sub moTextDate_Enter()
' Things to do on receiving focus
End Sub
Private Sub moTextDate_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)
If ValidateNumbers(KeyAscii, "/", ":", " ") = False Then KeyAscii = 0
End Sub
Private Sub moTextDate_Exit(ByVal Cancel As MSForms.ReturnBoolean)
' Things to do when lost focus
End Sub
例如:
import importlib
# works like C's #include, you always call it with include(<path>, __name__)
def include(file, module_name):
spec = importlib.util.spec_from_file_location(module_name, file)
mod = importlib.util.module_from_spec(spec)
# spec.loader.exec_module(mod)
o = spec.loader.get_code(module_name)
exec(o, globals())
输出将是:
#### file a.py ####
a = 1
#### file b.py ####
b = 2
if __name__ == "__main__":
print("Hi, this is b.py")
#### file main.py ####
# assuming you have `include` in scope
include("a.py", __name__)
print(a)
include("b.py", __name__)
print(b)