Python import与from…import的区别

1. 引言
在使用Python编程时,我们经常需要使用其他模块或者包中的函数、类或变量。为了能够使用这些来自外部模块的功能,我们需要使用import语句或from...import语句来将外部模块导入我们的代码中。
在本文中,我们将详细讨论import和from...import之间的区别,包括语法的不同、使用方法的不同以及可能引发的命名冲突问题。
2. import语句
import语句是Python中用于导入模块的基本语法。通过使用import语句,我们可以将目标模块中的所有函数、类和变量导入到当前的命名空间中。
下面是import语句的一般形式:
import module_name
其中,module_name是我们要导入的目标模块的名称。
2.1 导入整个模块
当我们使用import语句导入一个模块时,我们需要使用module_name来访问模块中的函数、类和变量。为了访问其中的内容,我们需要使用module_name作为前缀,例如:
import math
print(math.pi) # 输出圆周率3.141592653589793
在这个例子中,我们使用import math将Python中的math模块导入到我们的代码中。然后,我们使用math.pi访问了模块中的圆周率值,并输出结果。
2.2 导入模块中的某个对象
除了导入整个模块外,我们还可以导入模块中的某个函数、类或者变量。
下面是导入某个对象的一般形式:
import module_name.object_name
在这个形式中,module_name是我们要导入的目标模块的名称,而object_name则是我们要导入的具体对象的名称。
例如,我们可以只导入math模块中的sqrt函数:
import math.sqrt
print(math.sqrt(16)) # 输出4.0
在这个例子中,我们使用import math.sqrt导入了math模块中的sqrt函数,并使用这个函数计算了16的平方根。
3. from…import语句
from...import语句是Python中另一种导入模块的方式。与import语句不同的是,from...import语句允许我们只导入目标模块中的某个函数、类或变量,而不是导入整个模块。
下面是from...import语句的一般形式:
from module_name import object_name
在这个形式中,module_name是我们要导入的目标模块的名称,而object_name则是我们要导入的具体对象的名称。
3.1 导入某个对象
与import语句不同,from...import语句允许我们直接使用object_name访问导入的对象,而不需要使用module_name作为前缀。
例如,我们可以直接导入math模块中的sqrt函数:
from math import sqrt
print(sqrt(16)) # 输出4.0
在这个例子中,我们使用from math import sqrt导入了math模块中的sqrt函数,并直接使用sqrt函数计算了16的平方根。
3.2 导入多个对象
除了导入单个对象外,我们还可以使用from...import语句一次性导入多个对象。
下面是一般形式:
from module_name import object_name1, object_name2, object_name3
例如,我们可以导入math模块中的sin和cos函数:
from math import sin, cos
print(sin(30)) # 输出0.5
print(cos(30)) # 输出0.86602540378
在这个例子中,我们使用from math import sin, cos一次性导入了math模块中的sin和cos函数,并分别计算了30度的正弦和余弦值。
4. 区别与使用建议
4.1 语法差异
import语句和from...import语句的主要差异在于语法。使用import语句时,我们需要在使用被导入对象时加上模块名作为前缀;而使用from...import语句时,则可以直接使用被导入对象的名称。
4.2 命名冲突问题
当我们使用import语句导入整个模块时,被导入模块中定义的函数、类和变量会添加到当前命名空间中,存在命名冲突的风险。
例如,假设我们同时导入math和cmath模块,且两个模块中存在相同名称的函数sqrt。在这种情况下,我们无法同时访问两个函数,因为其中一个函数会覆盖另一个函数。
import math
import cmath
print(sqrt(16)) # 报错:NameError: name 'sqrt' is not defined
为了解决这个问题,我们可以改用from...import语句来分别导入相同名称的函数。
from math import sqrt as math_sqrt
from cmath import sqrt as cmath_sqrt
print(math_sqrt(16)) # 输出4.0
print(cmath_sqrt(16)) # 输出(4+0j)
在这个例子中,我们使用from math import sqrt as math_sqrt导入了math模块中的sqrt函数,并使用from cmath import sqrt as cmath_sqrt导入了cmath模块中的sqrt函数。通过这种方式,我们在代码中可以分别使用math_sqrt和cmath_sqrt来访问这两个函数,避免了命名冲突。
4.3 使用建议
对于模块中的函数、类和变量较多的情况,推荐使用import语句导入整个模块,然后使用模块名作为前缀来访问其中的对象,以区分不同模块中可能存在的命名冲突。
对于只需要使用模块中的部分对象的情况,推荐使用from...import语句导入特定对象,这样可以直接使用对象名称,使代码更加简洁。
另外,我们还可以使用import...as语句给导入的模块、对象或变量指定别名。这可以避免命名冲突问题,并且在代码中使用更简洁的名称。
下面是给导入的模块math和对象sqrt指定别名的示例代码:
import math as m
from math import sqrt as s
print(m.sqrt(16)) # 输出4.0
print(s(16)) # 输出4.0
在这个例子中,我们使用import math as m给导入的math模块指定了别名m,并使用m.sqrt来访问模块中的sqrt函数;同时,我们使用from math import sqrt as s给导入的sqrt函数指定了别名s,并直接使用s来调用该函数。
通过给导入的模块、对象或变量指定别名,我们可以更灵活地使用它们,而不会与其他同名的对象冲突。
5. 示例代码
下面是一个综合应用import和from...import语句的示例代码:
import math
from math import sqrt
print(math.pi) # 输出圆周率3.141592653589793
print(sqrt(16)) # 输出4.0
from math import sin, cos
print(sin(30)) # 输出0.5
print(cos(30)) # 输出0.86602540378
import cmath
print(cmath.sqrt(-1)) # 输出1j
import math as m
from math import sqrt as s
print(m.sqrt(25)) # 输出5.0
print(s(25)) # 输出5.0
在这个示例中,我们先使用import语句导入了math模块,并通过math.pi访问了pi常量,再通过sqrt函数计算了16的平方根。
然后,我们使用from math import sin, cos同时导入了sin和cos函数,并分别计算了30度的正弦和余弦值。
接着,我们使用import cmath导入了cmath模块,并通过cmath.sqrt计算了-1的平方根。
最后,我们使用import math as m给导入的math模块指定了别名m,并使用m.sqrt访问了sqrt函数;同时,我们使用from math import sqrt as s给导入的sqrt函数指定了别名s,并直接使用s来调用该函数。
6. 小结
本文中我们详细讨论了import和from...import语句之间的区别,包括语法的差异、使用方法的不同以及可能引发的命名冲突问题。
在实际编程中,根据具体情况选择合适的导入方式十分重要。对于目标模块中的函数、类和变量较多的情况,推荐使用import语句导入整个模块,并使用模块名作为前缀来访问其中的对象。而对于只需要使用部分对象的情况,使用from...import语句导入特定对象可以使代码更加简洁。
另外,通过给导入的模块、对象或变量指定别名,我们可以避免命名冲突,使代码更加灵活和易读。
极客教程