未提供项目描述
项目描述
馅饼
安装和文档
pip install painless-import-extension
.
基本上只有一件事从包中导出pie
:
from pie import LoaderForBetterLife
它是一个抽象的泛型类型。当你想加载一个文件来 typeA
时,写一个这样的加载器:
class ALoader(LoaderForBetterLife[A]):
pass
IDE 和静态类型检查器将帮助您完成以下步骤来实现您期望的加载器,这就是我在这里所说的文档。
动机
操,我必须先说点什么。
一旦你使用 Python 导入钩子来支持扩展名为 '.py' 的文件,你会感到非常恶心,而且如果你足够熟练地使用 Python 内部的东西来跟踪PathFinder.find_spec
(通常是sys.meta_path[2].find_spec
或 sys.meta_path[1].find_spec
)的实现,那么糟糕的模块查找机制会导致你对 Pythonimport
语句的可靠性产生强烈的怀疑,最后很可能会导致一个人对编写可靠代码的信心崩溃。
我曾经遇到过这种情况,幸运的是,在使用它几个月后我没有从宿舍跳下来(并且知道它多年)。
因此,我意识到在使用 Python 的模块查找机制时,让人们远离被杀应该是我的责任,这可能会挽救几个人的生命。
什么是馅饼?
PIE,又名painless-import-extension,并非旨在提供 Python 导入系统的更高级别接口,但实际上对解决大多数相关问题很有用。
从技术上讲,PIE“什么也没做”,到目前为止,这个项目中涉及的所有代码都非常简单,即使是 Python 的新手也可以用任何问题彻底理解它。但是,PIE 很有用,因为它以最简单的方式展示了使用 Python 导入系统的健康思维模型,如果您想使用与 Python 相同的模块文件搜索策略,也是最实用的方式。
例如,如果您想data.json
通过 PIE 导入,除了 JSON 文件之外,您还应该准备一个仅将后缀更改为.py
(因此得到data.py
)的文件,并填写以下内容:
from pie.json_loader import JsonLoader
data = JsonLoader(__file__, __name__).load()
其中,JsonLoader(__file__, __name__).load()
将加载 JSON 数据。
看起来微不足道?是的,这是意料之中的,我告诉你,这种方式很强大,而且微妙地比json.load(pathlib.Path(__file__).with_suffix('.json').open())
.
一个 PIE 加载器,调用时发生了什么LoaderForBetterLife.load()
?
给定这样一个文件目录:
- proj
- data.json
- data.py
data.py
我们充满
from pie.json_loader import JsonLoader
data = JsonLoader(__file__, __name__).load()
接下来,当您导入时proj.data
,
-
第一次,发生了类似的
json.load
事情,JSON 是从data.json
. 但是,引入了一个默认的缓存系统,当你退出当前的 Python 解释器时,重新打开解释器来导入proj.data
-
第二次,
json.load
可能不会被调用。有几种情况:- 当
proj/data.json
不存在时,我们将从缓存在磁盘上的二进制文件中获取 JSON。 - 如果
proj/data.json
存在,我们将检查 的内容是否proj/data.json
已更改。如果为真,我们将proj/data.json
像第一次那样导入;否则,我们使用缓存的二进制内容。
- 当
当您加载 DSL(领域特定语言)或其他编译为 Python 的编程语言时,事情变得非常有用。
例如,我们给出一个加载muridesu语言脚本的实现(仅限 Python 3.7)。
检查test/zenzen_muridesu.py
,请注意,如果您使用的是 IDE,由于我们对 Python 类型提示的全面支持,您将获得良好的自动完成和静态检查体验。
from pathlib import Path
from typing import Union, Tuple
from muridesu.parse_stmts import parse_stmts as parse
from pie import LoaderForBetterLife
from types import CodeType
import marshal
class MuridesuLoader(LoaderForBetterLife[CodeType]):
def source_to_prog(self, src: bytes, path: Path):
mod = parse(src.decode('utf8'), str(path.absolute()))
code = compile(mod, self.file.with_suffix(self.suffix()), 'exec')
return code
def load_program(self, b: bytes):
return marshal.loads(b)
def dump_program(self, prog: CodeType):
return marshal.dumps(prog)
def suffix(self) -> Union[str, Tuple[str, ...]]:
return '.muridesu'
exec(MuridesuLoader(__file__, __name__).load(), globals())
中test/zenzen_muridesu.muridesu
,写下
class Animal {
func bark(self){
print("hoho")
}
}
class Dog <: Animal {
bark = fn (self) -> {
print("dogy")
}
}
list(
map(
fn (it) -> {
print(it.__class__)
it.bark()
},
[Dog(), Animal()]
)
)
导入test/zenzen_muridesu.py
将给出以下 STD 输出:
<class '__main__.Dog'>
dogy
<class '__main__.Animal'>
hoho
结论
确定你是否真的想引入importlib
?
当您只需要像搜索普通 python 文件一样搜索扩展文件时,请使用 PIE。
项目详情
painless_import_extension-0.2.2- py3 -none-any.whl 的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | ec39cee8bd202ea005f0f0fc398f447ccab30b1a9268e400bc65f37005dc66db |
|
MD5 | 0ba2e29541b05f901c079abb9655cb35 |
|
布莱克2-256 | f68fb3e6e8a161988b68a7f20b20f9e2dbc51ab87ebb794b5eda40c240b9c293 |