浅谈Python中的包

Package的定义(你以为的)

  • 你在很多的地方都能看到关于package的定义:在Python中在当前目录下有__init__.py文件的目录即为一个package。

  • 嗯,包括python目前的官网文档也是类似这么介绍的

    https://docs.python.org/zh-cn/3.9/tutorial/modules.html#packages
    
    Python 只把含 __init__.py 文件的目录当成包
    https://docs.python.org/3.9/tutorial/modules.html#packages
    
    The __init__.py files are required to make Python treat directories containing the file as packages

3.9如此,3.11也是的,可能是文档维护人员的工资没发?

Package的定义(应该是这样的)

  • 然在上面的文档中,有这样一句

    • 包是一种用“点式模块名”构造 Python 模块命名空间的方法
    • Packages are a way of structuring Python’s module namespace by using “dotted module names”.

我认为是比较符合当前的设定的

是否需要初始化文件

https://realpython.com/lessons/package-initialization/

  • 看上面这个文章,尾部有这样的一段说明
Much of the Python documentation states that an __init__.py file must be present in the package directory when creating a package. This was once true. It used to be that the very presence of __init__.py signified to Python that a package was being defined. The file could contain initialization code or even be empty, but it had to be present.

Starting with Python 3.3, Implicit Namespace Packages were introduced. These allow for the creation of a package without any __init__.py file. Of course, it can still be present if package initialization is needed. But it is no longer required.
  • 简陋的翻译一下
很多的python文档说__init__.py必须要存在于package目录中,当你创建一个package的时候(注:事实上IDE如pycharm也是这么做的,默认就给你创建了..)。这曾经是对的。曾经它出现在一个python的目录中就表示了你在创建一个包。这个__init__.py文件可以包含初始化文件或者为空,但它必须存在。

从Python3.3开始,开始引入了隐式命名空间包的概念。这就允许了创建包的时候不需要__init__.py。当然如果一个包要初始化,它仍然是需要的。但是,不再是必要的!

PEP 420 Implicit Namespace Packages

  • 在Specification章节

    Regular packages will continue to have an __init__.py and will reside in a single directory.
    
    Namespace packages cannot contain an __init__.py
  • 它也提到了namespace packages和regular packages的区别

    • Portions of namespace packages need not all come from the same directory structure, or even from the same loader. Regular packages are self-contained: all parts live in the same directory hierarchy.
    • Namespace packages have no __file__ attribute.
    • Namespace packages’ __path__ attribute is a read-only iterable of strings, which is automatically updated when the parent path is modified.
    • Namespace packages have no __init__.py module.
    • Namespace packages have a different type of object for their __loader__ attribute

这个区别实在不好测试,比想象的要繁琐很多

一个简单的测试

  • 目录结构

    D:\pythonProject\AutoTest\PackageTest (7.08KB)
    
    ├── NamespacePack (2b)
    
    │   ├── demoNP.py (24b)
    
    ├── RegularPack (35b)
    
    │   ├── demoRP.py (24b)
    
    │   ├── __init__.py (2b)
    
    └── testPack.py (114b)
    
    
  • 区别就是在pycharm上创建一个目录NamespacePack,创建一个package(RegularPack)

  • demoNP.py

    nameNP = 'NamespacePack'
  • demoRP.py

    nameRP = 'RegularPack'
  • __init__.py为空

  • testPack.py

    from NamespacePack.demoNP import nameNP
    from RegularPack.demoRP import nameRP print(nameNP) # 输出NamespacePack
    print(nameRP) # 输出RegularPack
  • 跟普通的包似乎没有任何区别(至少我感知不到)

说在最后

  • 初学者(我也算)无需纠结细节
  • 只需知道python中的包并不一定要__init__.py,over

浅谈Python中的包的更多相关文章

  1. 浅谈python中得import xxx,from xxx import xxx, from xxx import *

    在python中import跟from import都是用来导入的,但是导入的机制不同 1.import xxx:导入模块,或者文件夹,对于调用模块或者文件夹中子模块的变量或者函数,需要使用" ...

  2. 浅谈python中的“ ==” 与“ is”

    在python中,== 与 is 之间既有区别,又有联系,本文将通过实际代码的演示,力争能够帮助读到这篇文章的朋友以最短的时间理清二者的关系,并深刻理解它们在内存中的实现机制.扯淡的话不多说,下面马上 ...

  3. 浅谈python中文件和文件夹的相关操作

    文件操作 文件的打开与关闭 打开文件 使用open(文件名,访问方式)函数,可以打开一个已存在的文件,或者创建一个新的文件. 示例如下: f = open('test.txt') # 访问方式可以省略 ...

  4. 浅谈python中字典append 到list 后值的改变问题

    看一个例子 ? 1 2 3 4 d={'test':1} d_test=d d_test['test']=2 print d 如果你在命令行实践的话,会发现你改动的是d_test ,但是d 也跟着改变 ...

  5. 浅谈python中的闭包函数

    闭包函数初探 通常我们定义函数都是这样定义的 def foo(): pass 其实在函数式编程中,函数里面还可以嵌套函数,如下面这样 def foo(): print("hello worl ...

  6. 浅谈python中的“ ==” 与“ is”、还有cmp

    总之,比较内容相等使用 ‘==’ 1.is" 是用来比较 a 和 b 是不是指向同一个内存单元,而"=="是用来比较 a 和 b指向的内存单元中的值是不是相等 2.pyt ...

  7. 浅谈Python中函数式编程、面向对象编程以及古怪的PythonIC

    1.函数式编程作为结构化编程的一种,正在受到越来越多的重视.那么什么事函数式编程呢? 在维基百科中给出了详细的定义,函数式编程又称泛函数编程,是一种编程规范,它将函数运算视为数学上的函数计算.简单的来 ...

  8. 浅谈python中selenium库调动webdriver驱动浏览器的实现原理

    最近学web自动化时用到selenium库,感觉很神奇,遂琢磨了一下,写了点心得. 当我们输入以下三行代码并执行时,会发现新打开了一个浏览器窗口并访问了百度首页,然而这是怎么做到的呢? from se ...

  9. 浅谈python中__str__和__repr__的区别

    很多时候我们在创建一个类的时候,在终端打印类或者查看的时候一般都不会得到一个太满意的结果 class T: def __init__(self): self.color="red" ...

  10. 浅谈Python 中 __getattr__与__getattribute__的区别

    __getattr__与__getattribute__均是一般实例属性截取函数(generic instance attribute interception method),其中,__getatt ...

随机推荐

  1. android学习 基础知识

    布局管理器 大小用dp; 字体用sp 线性布局 与 相对布局是可以嵌套使用的,根据实际需求,灵活使用. 1.通用属性 # 大小相关 layout_width="100dp":宽度 ...

  2. 关于ASP.NET Core WebSocket实现集群的思考

    前言 提到WebSocket相信大家都听说过,它的初衷是为了解决客户端浏览器与服务端进行双向通信,是在单个TCP连接上进行全双工通讯的协议.在没有WebSocket之前只能通过浏览器到服务端的请求应答 ...

  3. django启动报错:DisallowedHost at /

    学习django第一天,第一次启动服务就报错,报错内容如下: DisallowedHost at / Invalid HTTP_HOST header: '192.168.116.22:8000'. ...

  4. Redis系列11:内存淘汰策略

    Redis系列1:深刻理解高性能Redis的本质 Redis系列2:数据持久化提高可用性 Redis系列3:高可用之主从架构 Redis系列4:高可用之Sentinel(哨兵模式) Redis系列5: ...

  5. 如何发布一个 TypeScript 编写的 npm 包

    前言 在这篇文章中,我们将使用TypeScript和Jest从头开始构建和发布一个NPM包. 我们将初始化一个项目,设置TypeScript,用Jest编写测试,并将其发布到NPM. 项目 我们的库称 ...

  6. 【十次方微服务后台开发】Day02:加密与JWT鉴权、微服务注册中心、配置中心、熔断器、网关、消息总线、部署与持续集成、容器管理与监控Rancher、influxDB、grafana

    一.密码加密与微服务鉴权JWT 1.BCrypt密码加密 Spring Security 提供了BCryptPasswordEncoder类,实现Spring的PasswordEncoder接口使用B ...

  7. 爬了10000张NASA关于火星探索的图片,我发现了一个秘密

    前言 最近,我使用爬虫技术,爬取了美国航空航天局,也就是你电影里经常见到的 NASA, 火星探索的相关图片,有 10000 张吧. 嗯嗯,小事情,小事情. 完事儿之后,有点小激动,于是就有了这篇文章, ...

  8. ADB命令快速入门

    什么是ADB adb的全称为Android Debug Bridge,就是起到调试桥的作用.通过adb我们可以方便调试Android程序. 环境搭建 1需要java环境: 安装完JDK需要配置环境变量 ...

  9. uni-app 动态修改主题色

    老是碰到初版制作完成没多久,就整一出说什么要更改整个项目的色彩体系.真的是宝宝心里苦啊! 起初都是通过uni项目自带的uni.scss中定义,在替换页面上对应的css.以便于达到一次性修改整体布局的样 ...

  10. MongoDB 强制使用索引 hint

    转载请注明出处: 虽然MongoDB 查询优化器一般工作的很不错,但是也可以使用 hint() 来强迫 MongoDB 使用一个特定的索引.在这种方法下某些情形下会提升性能. 一个有索引的 colle ...