Python中import的细节

防忘系列...

Pycharm并没有IDEA一样可以设置对import进行排序以及自动消除没用到的库(要用快捷键Ctrl + Alt + O), 并且如果导入方式不正确会 1.找不到自定义包 2.Pycharm对指定内容报错(下划线或红线)

Python中模块,包,库概念

模块:就是<u>.py文件</u>,里面定义了一些函数和变量,需要的时候就可以导入这些模块。

:在模块之上的概念,为了方便管理而将文件进行打包。包目录下第一个文件便是__init__.py,然后是一些模块文件和子目录,假如子目录中也有__init__.py,那么它就是这个包的子包了。

:具有相关功能模块、包的集合。这也是Python的一大特色之一,即具有强大的标准库、第三方库以及自定义模块。

标准库:就是下载安装的python里那些自带的模块,要注意的是,里面有一些模块是看不到的比如像sys模块,这与linux下的cd命令看不到是一样的情况。

第三方库:就是由其他的第三方机构,发布的具有特定功能的模块。

自定义模块:用户自己可以自行编写模块,然后使用。

总结: 我们pip install <package>安装的是库,库下有很多包,我们在自己的项目文件中import有以下几种用法:

  • import numpy as np
  • import urllib.parse import urlencode
  • from lxml import HTML

之前大家应该碰到过,命名自己pip install xx安装的是叫xx的库,但是在用的时候写的却是from yy import zz,明显不对应嘛。因此,其实库和包的区别还可以通过setup.py打包成库来看。——使用setup.py打包python文件Python实现打包成库供别的模块调用

其中比较重要的就是5.编写:setup.py

注意:setup.py与要打包的test_package包同在bricewulib根目录下。

其中比较重要的几项是:name,version,packages

  • name:描述的是你打包的文件夹名。
  • version描述的是文件的版本号。
  • packages是所有要打包的包(package),这里需要打包的是test_package包以及test_package包下的test_package。输入python setup.py sdist然后就能创建bricewulib库,使用test_package包
setup(
    name = "bricewulib",
    version = "1.0",
    packages=["test_package","test_package.test_package2"]
)

import推荐顺序

我们推荐所有的模块在 Python 模块的开头部分导入。 而且最好按照这样的顺序:

  1. Python 标准库模块
  2. Python 第三方模块
  3. 应用程序自定义模块

通过空行来分割——(Python's Style Guide), PEP8 。

import的搜索顺序:

  1. 首先判断这个module是不是built-in即内建模块,如果是则引入内建模块,如果不是则在一个称为sys.path的list中寻找
  2. sys.path在python脚本执行时动态生成,包括以下3个部分:
  • 脚本执行的位置,即当前路径
  • 环境变量中的PYTHONPATH, 即.bash_profilec.
  • 安装python时的依赖位置

Python的import机制

运行、编写Python代码时,一定要注意的是脚本路径和脚本执行路径,以及相对路径和绝对路径

如果在项目中运用了相对路径,则一定要注意脚本执行路径

假设A是B的父目录, 如我们想在A目录调用B中模块, 而B中模板是又import了A下模板, 如login: from login import ftSession命令行在A路径下输入python B/main.py时, 会报错。因为import其实就是在搜索目录下按相对路径找的。

Pycharm的坑:

借鉴: Python的import机制坑在哪?

pycharm里打出来的路径是更多的,它把项目根目录加进去了。(也可以设置: 进入设置,找到Console下的Python Console,勾选选项“Add source roots to PYTHONPAT” )

查看搜索路径:print(sys.path)

settings.jpg

What's resource root?

Source roots (or source folders; shown asm).
These roots contain the actual source files and resources. PyCharm uses the source roots as the starting point for resolving imports.
The files under the source roots are interpreted according to their type. PyCharm can parse, inspect, index, and compile the contents of these roots.

以上导致的问题就是:

pycharm中,project folder是默认的source root,当你使用import语句导入模块时,Pycharm默认在project folder中寻找;所以当你在project folder下的某个subfolder导入某个同样定义在这个subfolder中的模块时,会出现导入错误。

pycharm中的第一个文件夹,即代表项目, 当在其中再次建立文件夹时,是按package处理的

如果要在这些文件夹内import其他文件,需要将完整路径导入进来

所以最终在Pycharm中导入的方式有两种: burning回答

  • 从project folder开始相对导入
  • 将module文件夹直接定义为source root

pycharm在同目录下import划红线但实际可以运行

解决方法: 右键将model所在的文件夹设置为source root

总结:python该如何import

需要明确的一点是:在运行Python脚本的时候,Python解释器会把脚本执行的位置,即当前路径加入到搜索路径中,而绝大多数情况main函数就在工程根目录,因此对于一个工程而言,最好的是从从project folder(工程根目录,即运行main函数的那个入口文件)开始相对导入

▲需要注意的是,对于main函数如果不在根目录,而是在工程目录的子目录中的情况,需要在main.py中自己手动添加sys.path.append(".."),即想办法把工程根目录加到搜索目录中,这样以后就可以又开始从工程根目录开始import了。

还有一个对于初学者可能会产生自我怀疑的点,我也顺便提一下好了

from config import *
// 等价于
from .config import *

__init__文件作用

在Python工程里,当python检测到一个目录下存在__init__.py文件时,python就会把这个目录当成一个包(package)。Module跟C++的命名空间和Java的Package的概念很像,都是为了科学地组织化工程,管理命名空间。

__init__.py的设计原则

__init__.py的原始使命是声明一个模块,所以它可以是一个空文件。

A、不要污染现有的命名空间。模块一个目的,是为了避免命名冲突,如果你在种用init.py时违背这个原则,是反其道而为之,就没有必要使用模块了。

B、利用__init__.py外提供类型、变量和接口,对用户隐藏各个子模块的实现。一个模块的实现可能非常复杂,你需要用很多个文件,甚至很多子模块来实现,但用户可能只需要知道一个类型和接口。就像我们的arithmetic例子中,用户只需要知道四则运算有add、sub、mul、dev四个接口,却并不需要知道它们是怎么实现的,也不想去了解arithmetic中是如何组织各个子模块的。由于各个子模块的实现有可能非常复杂,而对外提供的类型和接口有可能非常的简单,我们就可以通过这个方式来对用户隐藏实现,同时提供非常方便的使用。

C、只在init.py中导入有必要的内容,不要做没必要的运算。像我们的例子,import arithmetic语句会执行__ini__.py中的所有代码。如果我们在__init__.py中做太多事情,每次import都会有额外的运算,会造成没有必要的开销。一句话,init.py只是为了达到B中所表述的目的,其它事情就不要做啦。

上述来自: https://zhuanlan.zhihu.com/p/115350758

__all__变量

__all__是一个字符串list;

约束作用:用来定义模块中对于from XXX import *时要对外导出的符号,即要暴露的借口,但它只对import *起作用(即如果在使用脚本中对当前包使用import *,那么可以管理当前包下模块的导入情况),对from XXX import XXX不起作用。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,530评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,403评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,120评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,770评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,758评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,649评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,021评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,675评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,931评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,751评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,410评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,004评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,969评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,042评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,493评论 2 343

推荐阅读更多精彩内容

  • 当前目录 和 脚本目录 参考资料:https://techibee.com/python/get-current-...
    ThomasYoungK阅读 10,772评论 0 11
  • 模块和包 一 模块 1 什么是模块? 常见的场景:一个模块就是一个包含了python定义和声明的文件,文件名就是...
    go以恒阅读 2,261评论 0 4
  • 1. 函数的定义与使用 1.1 函数的定义 1.2 函数的基本调用 1.3 函数的使用技巧(==IMPORTANT...
    c0b2b66e5dc4阅读 258评论 0 1
  • A:概念解释: 模块:.py文件 包:一个目录结构,包含__init__.py文件的目录 库:完成一定功能的代码集...
    hello_我的哥阅读 627评论 0 1
  • 久违的晴天,家长会。 家长大会开好到教室时,离放学已经没多少时间了。班主任说已经安排了三个家长分享经验。 放学铃声...
    飘雪儿5阅读 7,480评论 16 22