Python3中__init__.py文件介绍
Python中的模块是包含Python定义和语句的文件(A module is a file containing Python definitions and statements),其文件名是模块名加后缀名.py。在模块内部,通过全局变量__name__可以获取模块名。
模块包含可执行语句及函数定义。这些语句用于初始化模块,且仅在import语句第一次遇到模块名时执行。
模块有自己的私有符号表,用作模块中所有函数的全局符号表。因此,在模块内使用全局变量时,不用担心与用户定义的全局变量发生冲突。另一方面,可以用与访问模块函数一样的标记法,访问模块的全局变量:modname.itemname
可以把其它模块导入模块。按惯例,所有import语句都放在模块(或脚本)开头,但这不是必须的。导入的模块名存在导入模块的全局符号表里。
import语句有一个变体,可以直接把模块里的名称导入到另一个模块的符号表,如下:这段代码不会把模块名foo导入到局部符号表里
from foo import foo_func, save
还有一种变体可以导入模块内定义的所有名称,如下:这种方式会导入所有不以下划线(_)开头的名称。大多数情况下,不要用这种功能,这种方式向解释器导入了一批未知的名称,可能会覆盖已经定义的名称
from foo import *
注意,一般情况下,不建议从模块或包导入*,因为,这项操作经常让代码变得难以理解。不过,为了在交互式编译器中少打几个字,这么用也没问题。
模块名后使用as时,直接把as后的名称与导入模块绑定,如下:与import foo一样,这种方式也可以有效地导入模块,唯一的区别是,导入的名称是ex_foo
import foo as ex_foo
from中也可以使用这种方式,效果类似,如下:
from foo import foo_func as foos
为了保证运行效率,每次解释器会话只导入一次模块。如果更改了模块内容,必须重启解释器。
以脚本方式执行模块:这项操作将执行模块里的代码,和导入模块一样,但会把__name__赋值为”__main__”: python foo.py <arguments>
模块搜素路径:导入spam模块时,解释器首先查找名为spam的内置模块。如果没找到,解释器再从sys.path变量中的目录列表里查找spam.py文件。
为了快速加载模块,Python把模块的编译版缓存在__pycache__目录中,文件名为module.version.pyc,version对编译文件格式进行编码,一般是Python的版本号。例如,CPython的3.8发行版中,foo.py的编译版本(compiled version)缓存为__pycache__/foo.cpython-38.pyc。使用这种命名惯例,可以让不同Python发行版及不同版本的已编译模块共存。Python对比编译版本与源码的修改日期,查看它是否已过期,是否要重新编译,此过程完全自动化。此外,编译模块与平台无关,因此,可在不同架构系统之间共享相同的支持库。
Python在两种情况下不检查缓存:(1).从命令行直接载入模块,只重新编译,不存储编译结果。(2).没有源模块,就不会检查缓存。
Python中的包(package)是一种通过使用”点式模块名(dotted module names)”来构建Python模块命名空间的方法。例如,模块名A.B表示包A中名为B的子模块。导入包时,Python搜索sys.path里的目录,查找包的子目录。
Python只把含__init__.py文件的目录当成包(Python3.2之后的版本不需要再额外的去专门创建一个__init__.py文件)。最简情况下,__init__.py只是一个空文件,但该文件也可以执行包的初始化代码,或设置__all__变量。当import指定的包时,此包内的__init__.py会被隐性执行,且只执行一次。
注意:使用from package import item时,item可以是包的子模块(或子包),也可以是包中定义的函数、类或变量等其它名称。import语句首先测试包中是否定义了item;如果未在包中定义,则假定item是模块,并尝试加载。如果找不到item,则触发ImportError异常。相反,使用import item.subitem.subsubitem句法时,除最后一项外,每个item都必须是包;最后一项可以是模块或包,但不能是上一项中定义的类、函数或变量。
import语句使用如下惯例:
(1).如果包的__init__.py代码定义了列表__all__,运行from package import *时,它就是用于导入的模块名列表。发布包的新版本时,包的作者应更新此列表。即如果显式声明了__all__,import *就只会导入__all__列出的成员,如果__all__定义有误,会抛出异常。
(2).如果没有定义__all__,from package.subpackage import *语句不会把包package.subpackage中所有子模块都导入到当前命名空间;该语句只确保导入包package.subpackage(可能还会运行__init__.py中的初始化代码),然后再导入包中定义的名称。这些名称包括__init__.py中定义的任何名称(以及显式加载的子模块),还包括之前import语句显式加载的包里的子模块。
包中含有多个子包时,可以使用绝对导入引用兄弟包中的子模块。还可以用import语句的from module import name形式执行相对导入。这些导入语句使用前导句点表示相对导入中的当前包(.)和父包(..),如下:
from . import echo
from .. import formats
Python包有多种结构。每个.py文件可作为单个模块。__init__.py文件定义方式如下,也可以使用不同方式的组合:
第一种方式:from .module import *
优点:
(1).用户不需要知道模块名称,例如,哪个功能在哪个模块中,他们只需要包名和函数名。
(2).导入顶级包(import top-level package)后,用户可以访问任何功能。
(3).制表符(Tab-completion)会补全为你提供的所有内容。
(4).当模块添加新特性时,不需要更新任何导入语句,它们将自动被包含。
缺点:
(1).要求所有函数和类必须命名唯一,即在模块中不能含有相同名字的函数。在模块中若含有相同名字的函数,虽然可能不会报错,但是调用的函数可能未必是你希望的那个。
(2).如果包很大,它会向命名空间添加很多内容,并且会减慢速度。
(3).对于有些函数防止用户调用的话,还需要作单独处理,如使用下划线来防止函数导入。
建议:
(1).在难以预测用户的工作流程时使用。
(2).当用户可能经常在不同模块之间来回切换时使用。
(3).当用户仅与几个模块(a few modules)一起使用。如果有很多模块,新用户可能更难在文档中找到他们想要的功能。
(4).在可能频繁添加或删除对象(object)时使用。
第二种方式:from .module import func 或 from .module import func1, func2
优点:
(1).拥有第一种方式的所有优点,并更容易控制哪些对象可供用户使用。
缺点:
(1).如果有许多模块,并且每个模块中有许多函数,那么__init__.py中内容会变得非常混乱。
(2).当向模块中添加新类或函数时,它们也必须显式添加到__init__.py文件中。
建议:
(1).当你的模块由单个类组成时特别有用。
(2).当你有少量对象要导入时使用。
(3).当你的对象具有明确名称时使用。
(4).当你确切地知道你的用户需要哪些对象以及他们不需要哪些对象时使用。
(5).当你不希望频繁添加大量需要导入的新模块和对象时使用。
第三种方式:import package.module
优点:
(1).简化了__init__.py文件,仅在添加新的模块时才需要更新。
(2).它是灵活的,它可用于仅导入用户需要的内容或导入所有内容。
(3).使用别名可以清理长的package.module规范(例如, import matplotlib.pyplot as plt)。
(4).可以有多个同名对象(例如,foo和bar模块中都调用了save()的函数)。
缺点:
(1).一些导入方法会使代码阅读起来更复杂,例如,foo.foo_func()不指示foo来自哪个包。
(2).最易读的方法(import test_package,没有别名)可能会导致长代码块(例如, test_package.foo.foo_func())使事情变得混乱。
(3).用户很难找到所有可能的功能。
建议:
(1).当你有一系列复杂的模块时使用,其中大多数用户永远不需要。
(2).import test_package导入大量对象时使用,可能会很慢。
(3).当你可以为不同类型的用户定义非常清晰的工作流程时使用。
(4).当你期望用户能够很好地浏览你的文档时使用。
第四种方式:使用__all__
注:以上内容及以下测试代码主要来自于:
1. https://towardsdatascience.com/whats-init-for-me-d70a312da583
2. https://docs.python.org/zh-cn/3/tutorial/modules.html
测试代码组织结构如下:顶层目录有一个test_package_main.py文件和一个test_package目录,test_package目录下有4个.py文件,各个文件内容如下:
test_package_main.py:
import sysvar = 4if var == 1: # 第一种方式,导入模块中所有内容import test_packagetest_package.foo_func()test_package.bar_func()test_package.baz_func()test_package.save() # 不能确定调用的是bar.py中的是还是foo.py中的. 由__init__.py决定,会调用后import的#test_package._calc() # AttributeError: module 'test_package' has no attribute '_calc'
elif var == 2: # 第二种方式,指定模块中要导入的内容,同一模块中若导入多个函数,中间用逗号分割: from .module import func1, func2import test_packagetest_package.foo_func()test_package.bar_func()test_package.baz_func()
elif var == 3: # 第三种方式# 用户可以采用三种不同的使用方法method = 3if method == 1:import test_packagetest_package.foo.foo_func()test_package.bar.bar_func()test_package.baz.baz_func()elif method == 2:from test_package import foo, bar, baz # 从包中导入子模块foo.foo_func()bar.bar_func()baz.baz_func()elif method == 3:import test_package.foo as ex_foo # 从包中导入单个模块import test_package.bar as ex_barimport test_package.baz as ex_bazex_foo.foo_func()ex_bar.bar_func()ex_baz.baz_func()ex_foo.save()ex_bar.save()print("csdn addr:", ex_foo.csdn_addr)print("sys path:", sys.path)print("dir:", dir(ex_foo)) # dir为内置函数,获取指定模块的方法列表,包括变量、函数等等
elif var == 4: # 使用__all__from test_package import * # import * 就只会导入__all__列出的成员foo.foo_func()bar.bar_func()#baz.baz_func() # NameError: name 'baz' is not defined
test_package/foo.py:
def foo_func():print("this is a foo function")def save():print("this is a foo save function")def _calc():print("this is a foo _calc function")github_addr = "https://github.com/fengbingchun"
csdn_addr = "https://blog.csdn.net/fengbingchun"
test_package/bar.py:
def bar_func():print("this is a bar function")def save():print("this is a bar save function")def _calc():print("this is a bar _calc function")
test_package/baz.py:
def baz_func():print("this is a baz function")
test_package/__init__.py:
# reference: https://towardsdatascience.com/whats-init-for-me-d70a312da583var = 4print("import package: test_package")if var == 1: # 第一种方式,导入模块中所有内容# from .module import *from .foo import *from .bar import *from .baz import *
elif var == 2: # 第二种方式,指定模块中要导入的内容,同一模块中若导入多个函数,中间用逗号分割: from .module import func1, func2# from .module import funcfrom .foo import foo_funcfrom .bar import bar_funcfrom .baz import baz_func
elif var == 3: # 第三种方式import test_package.fooimport test_package.barimport test_package.baz
elif var == 4: # 使用__all____all__ = ["foo", "bar"]
GitHub:https://github.com/fengbingchun/Python_Test
相关文章:
赠书 | 熵的实际应用,赌场和金融圈最著名的一个数学公式
本文选自湛庐文化策划出版图书《模型思维》。作者斯科特佩奇,超过100万用户的“模型思维课”主讲人。密歇根大学复杂性研究中心“掌门人”。圣塔菲研究所外聘研究员。曾出版《多样性红利》一书。斯科特佩奇以对社会科学多样性和复杂性的研究和建模面闻名。具体研究方…

Java传输对象模式
传输对象模式(Transfer Object Pattern)用于从客户端向服务器一次性传递带有多个属性的数据。传输对象也被称为数值对象。传输对象是一个具有 getter/setter 方法的简单的 POJO 类,它是可序列化的,所以它可以通过网络传输。它没有…

图片下方出现几像素的空白间隙
1、如何定义高度很小的容器? 在IE6下无法定义小高度的容器,是因为有一个默认的行高。 列举2种解决方案:overflow:hidden | line-height:0 2、图片下方出现几像素的空白间隙? 这个也有多种解决方案,如将img定义为displa…

Python3中Pillow(PIL)介绍
PIL全称为Python Imaging Library,是Python中的免费开源图像处理库。PIL的最新版本为1.1.7,于2009年9月发布,支持Python的最高版本到2.7。原始的PIL开发于2011年停止。随后,一个名为Pillow的后续项目fork了PIL的repository并增加了…
GitHub有望在中国开设子公司?
作者 | Financial Times译者 | 弯月,编辑 | 郭芮出品 | CSDN(ID:CSDNnews)作为世界上最大的软件开发平台,GitHub 自去年被微软以 75 亿美元收购后,一直颇受外界的争议。虽然在交易完成后,GitHub…

OC指示符assign、atomic、nonatomic、copy、retain、strong、week的解释
在使用property定义property时可以在property与类型之间用括号添加一些额外的指示符,常用的指示符有assign、atomic、nonatomic、copy、retain、strong、week、等。详情如下: assign: 简单赋值,不更改索引计数(Referen…

项目沟通管理计划
沟通计划包括决定项目涉及人的信息和沟通需求:谁需要什么信息;什么时候需要;怎么获得。虽然所有的项目都需要沟通项目信息,但信息需求和传播方式差别很大。确认涉及人的信息需求和决定满足需求的适当方式是项目获得成功的重要因素…

PyTorch中torchvision介绍
TorchVision包包含流行的数据集、模型架构和用于计算机视觉的图像转换,它是PyTorch项目的一部分。TorchVison最新发布版本为v0.11.1,发布较频繁,它的license为BSD-3-Clause。它的源码位于: https://github.com/pytorch/vision T…
百度ERNIE登顶GLUE榜单,得分首破90大关
出品 | AI科技大本营(ID:rgznai100)12月10日,百度ERNIE在自然语言处理领域权威数据集GLUE中登顶榜首,以9个任务平均得分首次突破90大关刷新该榜单历史,其表现超越微软MT-DNN-SMART, 谷歌T5、ALBERT等一众顶级预训练模…

Java 重写(Override)与重载(Overload)
TestDog.java /* * 重写(Override) * 重写是子类对父类的允许访问的方法的实现过程进行重新编写, 返回值和形参都不能改变。即外壳不变,核心重写! * 重写的好处在于子类可以根据需要,定义特定于自己的行为。 也就是说子类能够根据需要实现…

Oracle常用查看表结构命令
2019独角兽企业重金招聘Python工程师标准>>> select user from dual; //查看当前的用户名 select table_name from all_tables; //所有用户的表 select table_name from dba_tables; //包括系统表 select table_name from dba_tables where owner用户名 user_tabl…

TorchVision中使用FasterRCNN+ResNet50+FPN进行目标检测
TorchVision中给出了使用ResNet-50-FPN主干(backbone)构建Faster R-CNN的pretrained模型,模型存放位置为https://download.pytorch.org/models/fasterrcnn_resnet50_fpn_coco-258fb6c6.pth,可通过fasterrcnn_resnet50_fpn函数下载,此函数实现…

iOS-UIButton防止重复点击(三种办法)
目录 使用场景方法一 设置enabled或userInteractionEnabled属性方法二 借助cancelPreviousPerformRequestsWithTarget:selector:object实现方法三 通过runtime交换方法实现注意事项一 使用场景 在实际应用场景中,有几个业务场景需要控制UIButton响应事件的时间间隔。…
华为诺亚方舟开源预训练模型“哪吒”,4项任务均达到SOTA
出品 | AI科技大本营(ID:rgznai100)BERT之后,新的预训练语言模型XLnet、RoBERTa、ERNIE不断推出,这次,华为诺亚方舟实验室开源了基于BERT的中文预训练语言模型NEZHA(哪吒),寓意模型能…

音量调节助手(转)
源:音量调节助手 软件名称:音量调节助手 软件功能:通过键盘快捷键快速调节系统主音量 软件版本:V2014 软件作者:易几网络 操作系统:所有WINDOWS版本 开发工具:DELPHI XE …

TorchVision中通过AlexNet网络进行图像分类
TorchVision中给出了AlexNet的pretrained模型,模型存放位置为https://download.pytorch.org/models/alexnet-owt-4df8aa71.pth ,可通过models.alexnet函数下载,此函数实现在torchvision/models/alexnet.py中,下载后在Ubuntu上存放…
西湖龙井也上链?是的,以后你喝什么茶我都知道!
什么?区块链还可以帮忙法律取证?是的!就是这么牛13!区块链存证第一案12月9日,据《新华每日电讯》报道,杭州互联网法院用区块链提升审判效率。报道提到一个案例。2018年4月,杭州一家公司…

Java Enumeration接口
import java.util.Vector; import java.util.Enumeration; /* * Enumeration接口中定义了一些方法,通过这些方法可以枚举(一次获得一个)对象集合中的元素。 * 这种传统接口已被迭代器取代,虽然Enumeration 还未被遗弃࿰…
Windows Azure Pack与SCVMM标签解析分享
我在SCVMM上做了好CentOS6.5的VM模板镜像,自己部署也是成功的,现在配置WAP的VM云虚拟机角色配置,在SCVMM上我打好了CentOS6.5的标签,可是在创建虚拟机角色配置中,选择的CentOS却无法找到硬盘,这是怎么回事呢…

Linux下C++中可使用的3种Hook方法
Hook即钩子,截获API调用的技术,是将执行流程重定向到你自己的代码,类似于hack。如使程序运行时调用你自己实现的malloc函数代替调用系统库中的malloc函数。这里介绍下Linux下C中可使用的3中Hook方法: 1. GNU C库允许你通过指定适当…

Java Properties 类
Properties 继承于 Hashtable.表示一个持久的属性集.属性列表中每个键及其对应值都是一个字符串。 Properties 类被许多Java类使用。例如,在获取环境变量时它就作为System.getProperties()方法的返回值。 Properties 定义如下实例变量.这个变量持有一个Properties对…
国产数据库年终大盘点
作者 | 马超 编辑 | 胡巍巍出品 | CSDN(ID:CSDNnews)去“IOE”这个概念,最早由王坚院士在刚刚加入阿里时提出,其目标是将IBM 的小型机、Oracle数据库、EMC存储设备从阿里的IT体系中去除,代之以自主研发的系…

解密FFmpeg播放track mode控制
上一篇文章(http://www.cnblogs.com/yangdanny/p/4421130.html)我们解决了在FFmpeg下如何处理H264和AAC的扩展数据,根据解出的NALU长度恢复了H264的起始码和AAC的ADTS头,这样一般来说播放是没有问题。本篇文章来谈谈如何实现基于FFmpeg的track mode控制&…

UIButton防止按钮和手势的暴力点击
首先理解下几个概念 1、IMP:它是指向一个方法具体实现的指针,每一个方法都有一个对应的IMP,当你发起一个消息之后,最终它会执行的那段代码,就是由IMP这个函数指针指向了这个方法实现的 2、SEL:方法名称的描…

使用Windows7上的VS Code打开远程机Ubuntu上的文件操作步骤
之前在https://blog.csdn.net/fengbingchun/article/details/118991855 中介绍过在Windows10通过VS Code打开Ubuntu 16.04上的文件或文件夹的操作步骤。Windows7上的操作与Windows10有所不同,这里记录下。 Visual Studio Code Remote - SSH扩展允许你在任何远程机器…
微众银行殷磊:AI+卫星,从上帝视角洞察资产管理|BDTC 2019
出品 | AI科技大本营(ID:rgznai100)12月5日-7日,2019中国大数据技术大会(BDTC)于北京隆重举办,大会已成功举办十二届,是大数据领域极具影响力的行业盛会。本届大会汇聚了学术界、企业界上千位知…

【二分答案】【最短路】bzoj1614 [Usaco2007 Jan]Telephone Lines架设电话线
对于二分出的答案x而言,验证答案等价于将所有边权>x的边赋成1,否则赋成0,然后判断从1到n的最短路是否<K。 #include<cstdio> #include<cstring> #include<queue> using namespace std; #define N 1001 #define M 100…

Python3中装饰器@typing.overload的使用
typing.py的源码在:https://github.com/python/cpython/blob/main/Lib/typing.py 。此模块为类型提示(Type Hints)提供运行时支持。这里介绍下typing.overload的使用,从python 3.5版本开始将Typing作为标准库引入。 python3中增加了Function Annotation(…
19年NAACL纪实:自然语言处理的实用性见解 | CSDN博文精选
作者 | Nikita Zhiltsov翻译 | 王威力校对 | 李海明本文为你概述处理不同NLP问题时的具有卓越性能的方法、技术和框架等。计算语言:人类语言技术学会北美分会2019年年会(North American Chapter of the Association for Computational Linguistics: Huma…

高并发场景下数据库的常见问题及解决方案
一、分库分表 (1)为什么要分库分表 随着系统访问量的增加,QPS越来越高,数据库磁盘容量不断增加,一般数据库服务器的QPS在800-1200的时候性能最佳,当超过2000的时候sql就会变得很慢并且很容易被请求打死&a…