如何理解Python中包的引入


Posted in Python onMay 29, 2020

Python的from import *和from import *,它们的功能都是将包引入使用,但是它们是怎么执行的以及为什么使用这种语法呢?

从一模块导入全部功能

from import * means意味着“我希望能访问中我有权限访问的全部名称”。例如以下代码something.py:

# something.py
public_variable = 42
_private_variable = 141
def public_function():
 print("I'm a public function! yay!")
def _private_function():
 print("Ain't nobody accessing me from another module...usually")
class PublicClass(object):
 pass
class _WeirdClass(object):
 pass

在Python解释器中,我们可以执行from something import *,然后看到如下的内容:

>>> from something import *
>>> public_variable
42
>>> _private_variable
...
NameError: name '_private_variable' is not defined
>>> public_function()
"I'm a public function! yay!"
>>> _private_function()
...
NameError: name '_private_function' is not defined
>>> c = PublicClass()
>>> c
<something.publicclass object="" at="" ...="">
>>> c = _WeirdClass()
...
NameError: name '_WeirdClass' is not defined

from something import *从something中导入了除了以_开头名称外的其他所有名称,按照规范,_开始的名称是私有的所以未被导入。

上面没提到__all__是什么。__all__是一个字符串列表,指定了当from import *被使用时,模块(或者如后文会提到的包)中的哪些符号会被导出。如果我们不定义__all__(我们在上面的something.py就没定义),import *默认的导入方式是导入除了下划线(_)开头的所有名称。再说一次,编程惯例上下划线表示一个符号是私有的,不导入是合理的。让我们来看看在something.py中定义我们自己的__all__会发生什么。

# something.py
__all__ = ['_private_variable', 'PublicClass']
# The rest is the same as before
public_variable = 42
_private_variable = 141
def public_function():
 print("I'm a public function! yay!")
def _private_function():
 print("Ain't nobody accessing me from another module...usually")
class PublicClass(object):
 pass
class _WeirdClass(object):
 pass

现在,我们期望from something import *只会导入_private_variable和PublicClass:

# something.py
__all__ = ['_private_variable', 'PublicClass']
# The rest is the same as before
public_variable = 42
_private_variable = 141
def public_function():
 print("I'm a public function! yay!")
def _private_function():
 print("Ain't nobody accessing me from another module...usually")
class PublicClass(object):
 pass
class _WeirdClass(object):
 pass

包是怎样的呢?

当从一个包中导入全部时,__all__的做法和模块基本一样,不过它处理的是包中的模块(而不是把模块中的名都导入)。所以当我们使用from import *.时__all__说明了所有需要被导入当前命名空间的模块。

不同之处在于,如果你在一个包的__init__.py里面没有声明__all__,from import *语句不会导入任何东西(这个说法也不全对,正确的说法在此)

但是,这有什么不好?

继续读之前,在你的Python解释器中,执行import this,再读一遍Python之禅(在你孩子每晚睡前也要读给他们)。

明确比含糊要好。

from import * 是不明确的。它没告诉我们我们正在导入什么或者我们把什么带入当前命名空间了。更好的做法是显式地导入我们需要的全部名称。这种方式下,读者(非常可能是未来的你自己)就不会困惑于你代码中使用的一个变量/方法/类/其他东西是哪儿来的,这也告诉了我们下一点:

可读性很重要

即使你需要导入很多东西,一个一个显式地导入也更清楚。使用PEP 328:

from Tkinter import (Tk, Frame, Button, Entry, Canvas, Text,
 LEFT, DISABLED, NORMAL, RIDGE, END)

你现在就能明确知道你的命名空间里有什么,使用ctrl+f能很快地告诉你它们是哪儿来的。

同时,你还总是要承担模块/包作者更改list内容(加/减东西)的风险。

内容扩展:

基本注意点

  • 模块:一般指一个py文件;包:含有许多py文件的文件夹,含有 或不含有(Python3中允许)__init__文件。
  • 凡是在导入时带点的,点的左边都必须是一个包 (import a.fun1 其中a为py文件)这种导入形式是错误的。
  • 2.from a import fun1 a为一个py文件,fun1为该文件的属性或方法,这种导入形式是可以的。
  • 一般来说 import 后面不能带点,如:(from a import b.c是错误语法)
  • 导入模块时,是将模块的py文件导入进去(执行);导入包时,只会执行包中的__init__文件中的代码,故导入包时一般要导入到最底层,即from dir1.dir2.dir3 import py文件或者类、方法、属性,只有这样才能找到。但是你可以通过先导入一个包,然后在包的文件中的__init__中写相关的import语句(可以绝对,也可以相对),这样也可以通过import 包名 的方式将包中的东西导入进去。

以上就是如何理解Python中包的引入的详细内容,更多关于Python中包的引入详解的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
python使用cPickle模块序列化实例
Sep 25 Python
python使用WMI检测windows系统信息、硬盘信息、网卡信息的方法
May 15 Python
Python 列表理解及使用方法
Oct 27 Python
python 接口测试response返回数据对比的方法
Feb 11 Python
Python生成器generator用法示例
Aug 10 Python
python super的使用方法及实例详解
Sep 25 Python
Python+Selenium+phantomjs实现网页模拟登录和截图功能(windows环境)
Dec 11 Python
python算的上脚本语言吗
Jun 22 Python
opencv 图像滤波(均值,方框,高斯,中值)
Jul 08 Python
基于Django快速集成Echarts代码示例
Dec 01 Python
Python利用folium实现地图可视化
May 23 Python
基于Python编写简易版的天天跑酷游戏的示例代码
Mar 23 Python
浅谈django channels 路由误导
May 28 #Python
Python如何实现FTP功能
May 28 #Python
python基于socket函数实现端口扫描
May 28 #Python
Python中and和or如何使用
May 28 #Python
Python如何安装第三方模块
May 28 #Python
python使用多线程+socket实现端口扫描
May 28 #Python
Python如何实现定时器功能
May 28 #Python
You might like
DC《神奇女侠2》因疫情推迟上映 温子仁新恐怖片《恶性》撤档
2020/04/09 欧美动漫
用PHP产生动态的影像图
2006/10/09 PHP
在WINDOWS中设置计划任务执行PHP文件的方法
2011/12/19 PHP
ubuntu下编译安装xcache for php5.3 的具体操作步骤
2013/06/18 PHP
Zend Framework入门教程之Zend_Session会话操作详解
2016/12/08 PHP
javascript call方法使用说明
2010/01/11 Javascript
document.write()及其输出内容的样式、位置控制
2013/08/12 Javascript
JavaScript基本语法讲解
2015/06/03 Javascript
详解springmvc 接收json对象的两种方式
2016/12/06 Javascript
Three.js的使用及绘制基础3D图形详解
2017/04/27 Javascript
Vue动态实现评分效果
2017/05/24 Javascript
vue-router 权限控制的示例代码
2017/09/21 Javascript
微信小程序 按钮滑动的实现方法
2017/09/27 Javascript
JS实现百度搜索接口及链接功能实例代码
2018/02/02 Javascript
vue.js动画中的js钩子函数的实现
2018/07/06 Javascript
对vux点击事件的优化详解
2018/08/28 Javascript
JavaScript模拟实现自由落体效果
2018/08/28 Javascript
基于JQuery实现页面定时弹出广告
2020/05/08 jQuery
[20:21]《一刀刀一天》第十六期:TI国际邀请赛正式打响,总奖金超过550万
2014/05/23 DOTA
python实现聊天小程序
2018/03/13 Python
tensorflow tf.train.batch之数据批量读取方式
2020/01/20 Python
浅谈selenium如何应对网页内容需要鼠标滚动加载的问题
2020/03/14 Python
Windows下Anaconda和PyCharm的安装与使用详解
2020/04/23 Python
详解Open Folder as PyCharm Project怎么添加的方法
2020/12/29 Python
基于css3 animate制作绚丽的动画效果
2015/11/24 HTML / CSS
Puma印度官网:德国运动品牌
2019/10/06 全球购物
仓管员岗位职责范文
2013/11/08 职场文书
开学典礼主持词
2014/03/19 职场文书
数控技校生自我鉴定
2014/04/19 职场文书
新文化运动的口号
2014/06/21 职场文书
中文专业自荐书
2014/06/29 职场文书
2015年个人实习工作总结
2014/12/12 职场文书
离婚承诺书格式范文
2015/05/04 职场文书
无房证明样本
2015/06/17 职场文书
Pandas加速代码之避免使用for循环
2021/05/30 Python
Nginx如何获取自定义请求header头和URL参数详解
2022/07/23 Servers