我试图找到一个全面的指南,是否最好使用导入模块或从模块导入。我刚刚开始学习Python,我正试图从最佳实践开始。
基本上,我希望任何人都能分享他们的经验,其他开发者有什么偏好,以及避免任何陷阱的最佳方法是什么?
我试图找到一个全面的指南,是否最好使用导入模块或从模块导入。我刚刚开始学习Python,我正试图从最佳实践开始。
基本上,我希望任何人都能分享他们的经验,其他开发者有什么偏好,以及避免任何陷阱的最佳方法是什么?
当前回答
因为我也是初学者,我将尝试用一种简单的方式解释这一点: 在Python中,我们有三种类型的import语句,分别是:
1. 一般进口:
import math
这种类型的导入是我个人最喜欢的,这种导入技术的唯一缺点是,如果你需要使用任何模块的函数,你必须使用以下语法:
math.sqrt(4)
当然,它增加了输入工作,但作为初学者,它将帮助您跟踪与之相关的模块和函数(一个好的文本编辑器将大大减少输入工作,推荐使用)。
输入工作可以通过使用import语句进一步减少:
import math as m
现在,您可以使用m.s rt()而不是math.sqrt()。
2. 功能导入:
from math import sqrt
如果您的代码只需要访问模块中的单个或少数函数,则这种类型的导入最适合,但如果要使用模块中的任何新项,则必须更新import语句。
3.普遍的进口:
from math import *
虽然它大大减少了输入工作量,但不推荐,因为它将用模块中的各种函数填充代码,并且它们的名称可能与用户定义函数的名称冲突。 例子:
如果你有一个自己命名为sqrt的函数,并且你导入了math,你的函数是安全的:这是你的sqrt,这是math.sqrt。但是,如果从math import *执行,则会遇到一个问题:即,两个不同的函数具有完全相同的名称。来源:“
其他回答
import package
import module
对于import,令牌必须是一个模块(包含Python命令的文件)或一个包(sys。包含文件__init__.py的路径。)
当有子包时:
import package1.package2.package
import package1.package2.module
对文件夹(包)或文件(模块)的要求是相同的,但文件夹或文件必须在package2中,而package2必须在package1中,并且package1和package2都必须包含__init__.py文件。https://docs.python.org/2/tutorial/modules.html
使用import的from样式:
from package1.package2 import package
from package1.package2 import module
包或模块进入包含import语句的文件的命名空间为module(或包),而不是package1.package2.module。你总是可以绑定到一个更方便的名字:
a = big_package_name.subpackage.even_longer_subpackage_name.function
只有import的from样式允许你命名一个特定的函数或变量:
from package3.module import some_function
是允许的,但是
import package3.module.some_function
是不允许的。
这里还有一个没有提到的区别。这是从http://docs.python.org/2/tutorial/modules.html逐字复制的
注意,当使用
from package import item
项目可以是包的子模块(或子包),也可以是包中定义的其他名称,如函数、类或变量。import语句首先测试项目是否在包中定义;如果不是,则假定它是一个模块,并尝试加载它。如果找不到,则引发ImportError异常。
相反,当使用语法像
import item.subitem.subsubitem
除最后一项外,每一项都必须是一个包裹;最后一项可以是模块或包,但不能是前一项中定义的类、函数或变量。
这里还有另一个细节,没有提到,与写入模块有关。虽然这可能不太常见,但我时不时地需要它。
由于Python中引用和名称绑定的工作方式,如果你想更新模块中的某个符号,请输入foo。Bar,从模块外部,并有其他导入代码“看到”的变化,你必须以某种方式导入foo。例如:
模块foo:
bar = "apples"
模块一:
import foo
foo.bar = "oranges" # update bar inside foo module object
模块2:
import foo
print foo.bar # if executed after a's "foo.bar" assignment, will print "oranges"
但是,如果你导入的是符号名而不是模块名,这就行不通了。
例如,如果我在模块a中这样做:
from foo import bar
bar = "oranges"
没有代码在一个外部将看到bar作为“橙子”,因为我的bar设置只是影响模块a中的名称“bar”,它没有“到达”foo模块对象并更新它的bar。
我还想补充一点。如果遇到循环导入,了解Python如何将导入的模块作为属性处理可能会很有用。
我有以下结构:
mod/
__init__.py
main.py
a.py
b.py
c.py
d.py
我将使用不同的导入方法从main.py导入其他模块
main.py:
import mod.a
import mod.b as b
from mod import c
import d
Dis.dis显示了两者的区别(注意模块名,a b c d):
1 0 LOAD_CONST 0 (-1)
3 LOAD_CONST 1 (None)
6 IMPORT_NAME 0 (mod.a)
9 STORE_NAME 1 (mod)
2 12 LOAD_CONST 0 (-1)
15 LOAD_CONST 1 (None)
18 IMPORT_NAME 2 (b)
21 STORE_NAME 2 (b)
3 24 LOAD_CONST 0 (-1)
27 LOAD_CONST 2 (('c',))
30 IMPORT_NAME 1 (mod)
33 IMPORT_FROM 3 (c)
36 STORE_NAME 3 (c)
39 POP_TOP
4 40 LOAD_CONST 0 (-1)
43 LOAD_CONST 1 (None)
46 IMPORT_NAME 4 (mod.d)
49 LOAD_ATTR 5 (d)
52 STORE_NAME 5 (d)
55 LOAD_CONST 1 (None)
最后它们看起来是一样的(STORE_NAME在每个例子中都是result),但如果你需要考虑以下四个循环导入,这是值得注意的:
例二
foo/
__init__.py
a.py
b.py
a.py:
import foo.b
b.py:
import foo.a
>>> import foo.a
>>>
这是
example2
bar/
__init__.py
a.py
b.py
a.py:
import bar.b as b
b.py:
import bar.a as a
>>> import bar.a
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "bar\a.py", line 1, in <module>
import bar.b as b
File "bar\b.py", line 1, in <module>
import bar.a as a
AttributeError: 'module' object has no attribute 'a'
没说
青年们
baz/
__init__.py
a.py
b.py
a.py:
from baz import b
b.py:
from baz import a
>>> import baz.a
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "baz\a.py", line 1, in <module>
from baz import b
File "baz\b.py", line 1, in <module>
from baz import a
ImportError: cannot import name a
类似的问题……但显然,从x导入y并不等于从y导入x
example4
qux/
__init__.py
a.py
b.py
a.py:
import b
b.py:
import a
>>> import qux.a
>>>
这个也可以
我正在回答一个类似的问题,但在我发布之前,发帖者删除了它。这里有一个例子来说明这些区别。
Python库可以有一个或多个文件(模块)。为例子,
package1
|-- __init__.py
or
package2
|-- __init__.py
|-- module1.py
|-- module2.py
我们可以在任何基于设计需求的文件中定义python函数或类。
让我们来定义
在mylibrary1下的__init__.py中的Func1 () mylibrary2下的module2.py中的Foo()。
我们可以使用这些方法之一访问func1()
import package1
package1.func1()
or
import package1 as my
my.func1()
or
from package1 import func1
func1()
or
from package1 import *
func1()
我们可以使用以下方法之一来访问foo():
import package2.module2
package2.module2.foo()
or
import package2.module2 as mod2
mod2.foo()
or
from package2 import module2
module2.foo()
or
from package2 import module2 as mod2
mod2.foo()
or
from package2.module2 import *
foo()