考虑以下三个常规包及其内容的层次结构:
quick
??? brown
? ??? fox.py
? ??? __init__.py
??? lazy
? ??? dog.py
? ??? __init__.py
??? __init__.py
Run Code Online (Sandbox Code Playgroud)
现在假设jump模块中有一个函数,模块dog中需要它fox.我该怎么办?
最近看到Raymond Hettinger 在Pycon 2015上的 演讲我希望这个函数可以直接从包的根目录导入lazy,如下所示:
from lazy import jump
Run Code Online (Sandbox Code Playgroud)
此外,在我看来,编写相对导入更简洁,并使包内连接容易可见.因此,我将其写入lazy/__init__.py:
from .dog import jump
Run Code Online (Sandbox Code Playgroud)
这进入fox.py:
from ..lazy import jump
Run Code Online (Sandbox Code Playgroud)
但我想知道,这是正确的方法吗?
首先,导入名jump中lazy/__init__.py没有采取任何措施防止它直接被导入dog.如果某个功能可能从很多地方导入,会导致问题吗?例如,在单元测试中,我们是否可能从错误的位置修改名称?
此外,具有自动导入例程的IDE似乎更喜欢从定义函数的模块导入.我可以通过将字符_放在所有模块名称前面来覆盖它,但这似乎有点不切实际.
将包裹外所需的所有名称带到其他地方是否危险__init__.py?可能这至少增加了循环进口的可能性.但我想如果遇到循环导入,无论如何都会对包结构产生根本性的错误.
相对进口怎么样? PEP 8表示建议绝对进口:当它说绝对进口表现优于相对进口时,它意味着什么?能给我举个例子?
假设 C 是一个 Python 类,并假设 C 的构造函数采用整数作为参数。
现在考虑说明
x = C(0)
y = C(0)
Run Code Online (Sandbox Code Playgroud)
Python 的默认行为意味着 x 和 y 在内存中占据两个不同的位置。
是否可以强制 x 和 y 共享内存中的同一位置?
如果某个 Python 装饰器能够完成这项工作,我会非常高兴。
[注意]我正在寻找一种记忆构造函数的方法(有关函数记忆的信息,请参阅http://en.wikipedia.org/wiki/Memoization )。
【补充】 Sage开源数学软件通过类为这个问题提供了非常好的解决方案UniqueRepresentation(参见这里)。任何类都应该从该类继承以获得预期的行为。尽管如此,我想知道是否有一个纯Python的解决方案来解决这个问题。