python包导入方式import 和from import的区别和一些注意事项

一、import和from import的区别:

  1. import 只能导入模块、子包、包, 而不能导入模块中的类、函数、变量等
  2. from import 可以导入模块、子包、包、类、函数、变量以及在包的__init__.py中已经导入的名字
    ps: 但是两者都可以用as给导入的名字重命名

二、包导入的注意事项

  1. 不能在导入的路径中使用已经导入过的名字, 比如 import numpy as np; import np.random as rn, 这会报错, 说没有找到名字叫np的model, 这其实就说明python寻找包路径的时候, 是在文件系统中寻找, 而不包含当前命名空间中的名字, 即与当前的程序执行环境没有关系的
  2. 导入一个包时, 则这个包可用的属性都必须在__init__.py文件中定义, 这就是说如果一个包的__init__.py文件是空的, 则即使包里边有几个模块文件, 也无法通过这个包名去使用, 比如pkg下有a.py和b.py两个文件, 但是__init__.py中没有导入模块a和b,则import pkg as pg 后, 无法使用pg.a和pg.b,这个说明包内的模块和子包不会自动加入到包的名字空间里边, 需要手动通过__init__.py指定后才会加入。这一点上模块和包不太一样, 模块中的符号是自动导入的,因此可以直接通过模块名来调用
  3. 第2点只是说无法通过pg这个名字来使用模块a和b, 但是我们可以手动导入a和b的, 用import pkg.a as a和from pkgs import a as a都是可以的
  4. 导入一个长串的路径时, 则这个路径上的所有包的__init__.py都会被执行, 并且包的对应子包也会被加入到包的属性中去, 比如我们现在有这样一个包结构: pkgs下有两个子包pkga和pkgb, 且pkgs/init.py是空文件,则import pkgs语句是无法使用pkgs.pkga这样的句子的, 但是如果我们后续又使用了一个import语句: import pkgs.pkga.a as a,则此时pkgs的名字空间里会加入pkga这个属性,也就是可以使用pkgs.pkga了
    ps: from pkgs.pkga.a import fun_a这种长路径形式, 虽然会执行pkgs和pkga的__init__.py以及模块a的代码, 但是当前名字空间中并没有pkgs、pkga、a这些名字的,所以不能使用这些符号, 必须显示导入后才能使用
  5. 在__init__.py或模块中已经导入的名字是属于这个包或者模块的, 他们的使用方式和模块中定义的符号是一样的, 比如在pkgs/init.py中有import tensorflow as tf, 则import pkgs后, 可以直接使用pkgs.tf来使用tensorflow, 又比如在模块a中有import numpy as np, 则import pgks.pkga.a as a后, 可以使用a.np来使用numpy

ps: 最后再讲一个奇怪现象:就是在tensorflow下有python、core、tools等子包, 但是使用import tensorflow.python as pn和import tensorflow.core as ce会报错:AttributeError: module ‘tensorflow’ has no attribute ‘python’, 而 import tensorflow.tools as ts则没有出错, 并且很奇怪的是, 用from tensorflow import python 又是可以的, 正常来说from import和import的效果在这种情况下是一样的, 这里我猜是tensorflow对python和core的导入做了一些隐藏工作,因为这个异常是在tensorflow/python/util/deprecation_wrapper.py in getattr(self, name)中抛出的, 而且是一个AttributeError, 并不是python解释器自动抛出的:ModuleNotFoundError, 但是具体tf怎么实现的这个操作就没有去细究了

### Python 中 `import` 的用法及注意事项Python 编程中,`import` 是用于引入外部模块或的关键字。以下是关于如何正确使用 `import` 进行代码打以及需要注意的地方。 #### 1. 基本概念 - **Module**: 单个 `.py` 文件即为一个模块,可以通过 `import` 或者 `from ... import ...` 来加载其中的内容[^2]。 - **Package**: 是一种特殊的目录结构,用来组织多个模块。的根目录下必须存在一个名为 `__init__.py` 的文件(即使为空),表示该目录是一个可被导入。 #### 2. 使用方式 ##### (1) 导入整个模块 通过简单的 `import` 关键字可以将另一个模块整体载入当前命名空间: ```python import math print(math.sqrt(16)) ``` ##### (2) 部分导入 如果只需要特定的功能,则可以用如下形式仅导入所需的部分: ```python from os import path print(path.exists('/some/directory')) ``` 这种方式会更加高效并减少不必要的全局变量污染[^1]。 ##### (3) 别名处理 为了避免名称冲突或者简化调用路径,还可以给已导入的对象赋予新的名字: ```python import numpy as np array = np.array([1, 2, 3]) ``` #### 3. 注意事项 - 当执行像 `from xxx import func`这样的语句时,Python 解释器实际上仍需先完全运行目标模块一次;不过最终只会暴露指定函数到使用者环境中。 - 如果在一个脚本里定义了某些行为逻辑又希望别人能够方便地重用这些功能而不触发那些初始化操作的话,应该把它们放入专门的方法内部而不是裸写于顶层代码块之中[^3]。 例如,在 `m3.py` 中有这样一段代码: ```python # m3.py import m4 def printSelf(): print("In m3") if __name__ == "__main__": # 此处放置启动程序所需的唯一入口点指令集 pass ``` 上述例子展示了良好的实践——任何可能被执行多次的动作都应置于条件判断之下(`if __name__ == '__main__':`),从而确保当此文件作为库而非独立应用程序运行时不意外激活。 另外值得注意的是,虽然理论上支持多种扩展类型的文件(.pyo,.pyc等),但在实际开发过程中我们几乎总是专注于纯文本源码文件(*.py*)的形式来进行分享与协作。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值