如何理解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 相关文章推荐
python3 pillow生成简单验证码图片的示例
Sep 19 Python
利用scrapy将爬到的数据保存到mysql(防止重复)
Mar 31 Python
Python 实现两个服务器之间文件的上传方法
Feb 13 Python
详解Python传入参数的几种方法
May 16 Python
Python内置加密模块用法解析
Nov 25 Python
Django Serializer HiddenField隐藏字段实例
Mar 31 Python
jupyternotebook 撤销删除的操作方式
Apr 17 Python
浅谈TensorFlow之稀疏张量表示
Jun 30 Python
python urllib和urllib3知识点总结
Feb 08 Python
如何使用Python提取Chrome浏览器保存的密码
Jun 09 Python
教你使用一行Python代码玩遍童年的小游戏
Aug 23 Python
python_tkinter弹出对话框创建
Mar 20 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
后宫无数却洁身自好的男主,唐三只爱小舞
2020/03/02 国漫
php daodb插入、更新与删除数据
2009/03/19 PHP
php使用ZipArchive提示Fatal error: Class ZipArchive not found in的解决方法
2014/11/04 PHP
Linux系统下php获得系统分区信息的方法
2015/03/30 PHP
CI框架使用composer安装的依赖包步骤与方法分析
2016/11/21 PHP
PHP实现分布式memcache设置web集群session同步的方法
2018/04/10 PHP
PhpStorm 如何优雅的调试Hyperf的方法步骤
2019/11/24 PHP
Thinkphp框架+Layui实现图片/文件上传功能分析
2020/02/07 PHP
Prototype 学习 Prototype对象
2009/07/12 Javascript
extjs render 用法介绍
2013/09/11 Javascript
jQuery实现可用于博客的动态滑动菜单完整实例
2015/09/17 Javascript
JS中的==运算: [''] == false —&gt;true
2016/07/24 Javascript
javascript 正则表达式去空行方法
2017/01/24 Javascript
JS三目运算(三元运算)方法详解
2017/03/01 Javascript
nodejs实现连接mongodb数据库的方法示例
2018/03/15 NodeJs
angular6的table组件开发的实现示例
2018/12/26 Javascript
JavaScript中的垃圾回收与内存泄漏示例详解
2019/05/02 Javascript
Vue循环遍历选项赋值到对应控件的实现方法
2020/06/22 Javascript
[02:35]DOTA2英雄基础教程 狙击手
2014/01/14 DOTA
[03:46]显微镜下的DOTA2第七期——满血与残血
2014/06/20 DOTA
Python的多态性实例分析
2015/07/07 Python
python中私有函数调用方法解密
2016/04/29 Python
Python中index()和seek()的用法(详解)
2017/04/27 Python
Windows下将Python文件打包成.EXE可执行文件的方法
2018/08/03 Python
python单线程下实现多个socket并发过程详解
2019/07/27 Python
python字符串判断密码强弱
2020/03/18 Python
HTML5 video视频字幕的使用和制作方法
2018/05/03 HTML / CSS
html5指南-5.使用web storage存储键值对的数据
2013/01/07 HTML / CSS
JD Sports芬兰:英国领先的运动鞋和运动服饰零售商
2018/11/16 全球购物
舞会礼服和舞会鞋:PromGirl
2019/04/22 全球购物
Bluebella法国官网:英国性感内衣品牌
2019/05/03 全球购物
开放系统互连参考模型
2016/06/29 面试题
思想品德课教学反思
2014/02/10 职场文书
会计出纳岗位职责
2015/03/31 职场文书
2016年父亲节寄语
2015/12/04 职场文书
用Python进行栅格数据的分区统计和批量提取
2021/05/27 Python