python包引用问题
python模块引用梳理
文件组织结构:
复制代码
t
├── __init__.py
├── main.py
├── t1
│ ├── A.py
│ └── __init__.py
└── t2
├── B.py
└── __init__.py
复制代码
A.py
def test():
print 't.t1.A.test()'
B.py
def test():
print 't.t2.B.test()'
执行:
python t/main.py
问题1:
在main.py中引用t2/B的test方法,如何写?
方式1: from xxx import xxx
from t2 import B
B.test()
这个写法很糟糕, 但能解决目前问题。糟糕的地方在于隐晦的引入t2。更好的方式是相对引用。
from .t2 import B
B.test()
但如果用 python t/main.py执行会报错,此处原因请参考这。原因是相对引用默认作为包的方式才能运行。
正确执行方法(linux shell下): python -m t.main
这个写法也不够好!B在具体的代码行,看不出其出处。更好的方式是
from . import t2
t2.B.test()
但运行时会报错!
AttributeError: 'module' object has no attribute 'B'
大致意思是, 模块对象没有B属性!这点从java/.net转过来的也许有一点不习惯!
pythony引入一个模块(import m) <==> 引入m/__init__.py文件,里面有啥就有啥,反之亦然。
破解方法:
1. 不太好的方法有上一个代码例子, 即: from ... import ...2. 在模块的__init__.py文件中自动引入这些文件, 推荐最为最佳实践!此处修改 t/t2/__init__.py文件
import B
这样问题就完美结果了。总结下,最佳实践demo如下:
t/main.py
-- coding:utf-8 --
from . import t2
t2.B.test()
t/t2/__init__.py
-- coding:utf-8 --
from . import B
即:
- 相对引用
- 尽量引入更顶层包
- 通过命名空间引用具体的方法或者类
- 被引用包(子包)需要在__init__.py中声明(import)可以被外部直接访问的文件
问题2:
在t2/B中如何引用t1/A的test方法?
t/t2/B.py
from .. import t1
t1.A.test()
同时声明A
t/t1/__init__.py
from . import A
Python包的相对导入时出现错误的解决方法
在练习Python中package的相对导入时,即
from . import XXX
或者
from .. import XXX
时会遇到这样两个错误:
SystemError: Parent module '' not loaded, cannot perform relative import
和
ValueError: attempted relative import beyond top-level package
其实这两个错误的原因归根结底是一样的:在涉及到相对导入时,package所对应的文件夹必须正确的被python解释器视作package,而不是普通文件夹。否则由于不被视作package,无法利用package之间的嵌套关系实现python中包的相对导入。
文件夹被python解释器视作package需要满足两个条件:
1、文件夹中必须有__init__.py文件,该文件可以为空,但必须存在该文件。
2、不能作为顶层模块来执行该文件夹中的py文件(即不能作为主函数的入口)。
补充:在"from YY import XX"这样的代码中,无论是XX还是YY,只要被python解释器视作package,就会首先调用该package的__init__.py文件。如果都是package,则调用顺序是YY,XX。
另外,练习中“from . import XXX”和“from .. import XXX”中的'.'和'..',可以等同于linux里的shell中'.'和'..'的作用,表示当前工作目录的package和上一级的package。
举个例子:
目录树
testIm/
--__init__.py
--main.py : from Tom import tom
--Tom/
--__init__.py : print("I'm Tom's __init__!")
--tom.py : from . import tomBrother, from .. import Kate,print("I'm Tom!")
--tomBrother.py print(I'm Tom's Brother!)
--Kate/
--__init__.py : print("I'm Kate's __init__!")
--kate.py
运行文件:main.py
结果:
复制代码
I'm Tom's __init__!
I'm Tom's Brother!
Traceback (most recent call last):
File "D:PythonLearningTestIm2main.py", line 3, in
from cat import cat
File "D:PythonLearningTestIm2catcat.py", line 4, in
from .. import dog
ValueError: attempted relative import beyond top-level package
复制代码
可以看到from . import tomBrother顺利执行,首先执行了Tom文件夹下的__init__.py文件,后来执行了tomBrother.py文件,但是当执行到“from .. import dog”时报错,这是因为我们是在TestIm文件夹下把main.py文件作为主函数的入口执行的,因此尽管TestIm文件夹中有__init__.py文件,但是该文件夹不能被python解释器视作package,即Tom package不存在上层packge,自然会报错,相对导入时超出了最高层级的package。
修改方法:
目录树
test/
--main.py : from testIm.Tom import tom
--testIm/
--__init__.py
--Tom/
--__init__.py : print("I'm Tom's __init__!")
--tom.py : from . import tomBrother, from .. import Kate,print("I'm Tom!")
--tomBrother.py print(I'm Tom's Brother!)
--Kate/
--__init__.py : print("I'm Kate's __init__!")
--kate.py
运行文件:main.py
结果:
I'm top's __init__!
I'm Tom's __init__!
I'm Tom's Brother!!
I'm Kate's __init__!
I'm Tom!
即主函数入口不在TestIm中,则TestIm和其同样包含__init__.py文件的子文件夹都被python解释器视作package,形成相应的嵌套关系。可以正常使用from . import XXX和from .. import XXX。
致敬原创:
https://www.cnblogs.com/ArsenalfanInECNU/p/5346751.html
https://www.cnblogs.com/Tommy-Yu/p/5794829.html
相关文章:

【新周报(051)】Datawhale组队学习
记录: 按照本周规划,我们正在与阿里云天池合作开展“在线编程训练营”的组队学习活动,在这次活动中我们已经完成12个知识点(数组、链表、栈、字符串、树、位运算、双指针、搜索、排序、动态规划、分治、哈希表)的视频…

ZJU-java进阶笔记 第一、二周(类与对象,对象交互)
对象变量是对象的管理者,而非所有者 VendingMachine vm new VendingMachine();this指代当前对象 成员函数可以直接(不需要点运算符)调用本类的其他成员函数 void insertMoney(int amount) {balance balance amount;showBalance(); }定义…

常用的文本处理函数
函数说明left()返回串左边的字符length()返回串的长度locate()找出串的一个子串lower()将串转换成小写upper()将串转换成大写ltrim()去掉串左边空格rtrim()去掉串右边空格substring()返回子串的字符转载于:https://www.cnblogs.com/forphp/p/3442568.html

【青少年编程竞赛交流】02月份微信图文索引
02月份微信图文索引 由于“组队学习”这个公众号的功能主要是组织Datawhale社群中的学习者们每个月的组队学习,所以,我另外新建了这个微信公众号“青少年编程竞赛交流”,在这个公众号上分享有关青少年编程方面的知识,带小朋友们参…

js ~取非运算符的妙用,将-1转为0(或假值)
典型的运用场景就是indexOf

CSP 201912-1 报数 python实现
试题 代码 python n int(input())list [0, 0, 0, 0] m 0 i 1while(i < (mn)):if 7 in str(i) or i % 7 0:list[(i3) % 4] 1m 1i 1for j in list:print(j)

暴裂无声张一鸣
2009年,张一鸣第一次创业,项目名为九九房。最巅峰时,九九房的用户超过600万,移动产品用户量超过100万,日启动10万人次。如果这一项目成功地做下去,张一鸣很有可能成为一名地产大佬。可惜的是,张…

select 不要 用*
背景 说实在的,这有什么好记录的呢。记录这个有啥用,真是技术人员的吹毛求疵。说起来,就是给人装有用吧。既然记录了,也想个相关的段子吧。曾经有个同事写了个sql,效率极差,来了个女同事,竟然解…

【青少年编程竞赛交流】01月份微信图文索引
01月份微信图文索引 由于“组队学习”这个公众号的功能主要是组织Datawhale社群中的学习者们每个月的组队学习,所以,我另外新建了这个微信公众号“青少年编程竞赛交流”,在这个公众号上分享有关青少年编程方面的知识,带小朋友们参…

CSP 201812-1 小明上学 Python实现+详解
题目 代码 #红灯 r 秒,黄灯 y 秒,绿灯 g 秒 r,y,g [int(i) for i in input().split()]#n表示小明总共经过的道路段数和看到的红绿灯数目 n int(input())#0-道路 #1-红灯 需要等r(所读值取代)秒 #2-黄灯 需要等yr(所读值取代)秒(黄灯亮后亮红灯) #3-绿…

Debain 7.2安装配置
一 下载安装Debian 7.2 安装debian CD1,在最后一步,使用网络安装基本界面。 二 修改源 cd /etc/apt mv sources.list sources.list.bak gedit /sources.list 添加: #####################主要,开源,闭源 deb http://mirrors.163.c…

腾讯云与每日优鲜便利购战略签约 引领无人零售2.0时代发展
5月23日-24日,2018腾讯云未来峰会在广州保利世贸博览馆举行,在互联网专场上,腾讯云与每日优鲜便利购签订战略合作协议。双方表示,将充分融合每日优鲜便利购的建筑物级零售价值与腾讯云在云计算、大数据及AI技术的优势,…

青少年编程竞赛交流群第048次活动录播
背景介绍 把电子学会的青少年编程能力等级测评作为游戏的关卡,带着小朋友们升级打怪,这个想法来自于 我从邵慧宁身上得到的启发。 升级打怪: 电子学会考评中心:http://www.qceit.org.cn/bos/default.html 知识内容:…

ZJU-java进阶笔记 第三周(对象容器)
ArrayList<String> 读作 ArrayList of String 用来存放String的ArrayList ArrayList类属于范型类,是种容器 ArrayList<String>类属于容器类,用来存放对象,由容器类型和元素类型构成 知道容器类的一些内置用法,省很多事…

Nginx负载均衡配置实例详解
负载均衡是我们大流量网站要做的一个东西,下面我来给大家介绍在Nginx服务器上进行负载均衡配置方法,希望对有需要的同学有所帮助哦。负载均衡先来简单了解一下什么是负载均衡,单从字面上的意思来理解就可以解释N台服务器平均分担负载…

iOS 设置View阴影
iOS 设置View投影 需要设置 颜色 阴影半径 等元素 UIView *shadowView [[UIView alloc] init];shadowView.frame CGRectMake(100, 100, 100, 100);shadowView.center self.view.center;shadowView.backgroundColor [UIColor whiteColor];//设置阴影颜色shadowView.layer.sh…

ZJU-java进阶笔记 第四周(继承与多态)
继承是面向对象语言的重要特征之一,没有继承的语言只能被称作“使用对象的语言”。 子类从父类那里继承来了所有的成员 ① 除了构造函数,毕竟构造函数和父类同名 ② 得到不等于可以随便使用 如果我们试图重新定义一个在父类中已经存在的成员变量&…

浅谈《think in java》:一 对象导论总结
清单1. 抽象机制,面向对象程序设计方式 java所基于Smalltalk的特性表现一种纯粹的面向对象设计方式: 万物都是对象 程序是对象的集合(容器),他们通过发送消息(发送请求)来告知彼此所要做的。 每…

CSP 201812-2 小明放学 Python实现+详解
试题 代码 # 红灯 r 秒,黄灯 y 秒,绿灯 g 秒 r, y, g [int(i) for i in input().split()]# n表示小明总共经过的道路段数和看到的红绿灯数目 n int(input())# 定义getTime(k,t,time)函数计算时间开销 # k为0,1,2,3时…

《学习OpenCV》第三章习题 第3题
这是一个很有意思的题目,通过这个题我们可以理解图形的内部存储和cvPtr*D函数族的使用方法。 简单来说,图像就是矩阵,在一般的图像中,每个像素中存储了3个变量,分别代表BGR三通道的值,cvPtr*D函数族就是帮助…

给input type=color设置默认值
参考:https://stackoverflow.com/questions/14943074/html5-input-colors-default-color?utm_mediumorganic&utm_sourcegoogle_rich_qa&utm_campaigngoogle_rich_qa <input type"color"> 默认值为“#000000”, 想要更改默认值…

ZJU-java进阶笔记 第六周(抽象与接口)
abstract (1) 抽象类不可以用来制造对象,但可以用来定义变量,当然将来付给这个变量的一定是这个抽象类的非抽象子类的对象 (2) 抽象类的非抽象子类必须覆盖父类中的抽象函数,这种覆盖叫做实现两…

库存事务处理现有量检查
--检查现有量CURSOR c_lot_number(l_organization_id NUMBER,p_inventory_item_id IN NUMBER) ISSELECT mln.lot_number, mln.expiration_dateFROM mtl_lot_numbers mlnWHERE mln.inventory_item_id p_inventory_item_id-- AND mln.status_id 1 --有效合格批次AND mln.orga…

数据变金矿:一文读懂序列模型(附用例)
简介 众所周知,人工神经网络(ANN)的设计思路是模仿人脑结构。但是直到10年前,ANN和人类大脑之间唯一的共同点是对实体的命名方式(例如神经元)。由于预测能力较弱并且实际应用的领域较少,这样的神经网络几乎毫无用处。 …

ZJU-java进阶笔记 第七周(异常处理)
异常的定义 捕捉异常范例 try{//可能产生异常的代码 }catch(Type1 id1){//处理Type1异常的代码 }catch(Type2 id2){//处理Type2异常的代码 }catch(Type3 id3){//处理Type3异常的代码}异常捕捉的意义:异常发生,程序也不需要终止 3. 捕捉到异常对象后…

【组队学习】【35期】吃瓜教程——西瓜书+南瓜书
吃瓜教程——西瓜书南瓜书 航路开辟者:谢文睿、秦州领航员:凌亮航海士:谢文睿、秦州 基本信息 开源内容:https://github.com/datawhalechina/pumpkin-bookB站视频:https://www.bilibili.com/video/BV1Mh411e7VU内容…