python导入其他目录的文件_python如何跨目录读取非.py文件?

导入系统

要使用模块和库,需要先进行导入。

导入系统是相当复杂的,不过你可能已经了解了一些基本知识。这里会介绍一些关于这一子系统的内部机理。

sys模块包含许多关于Python导入系统的信息。首先,当前可导入的模块列表都是通过sys.moudle变量才可以使用的。它是一个字典,其中键(key)是模块名字,对应的值(value)是模块对象。

sys.modules['os']

许多模块是内置的,这些内置的模块在sys.builtin_module_names中列出。内置模块可以根据传入Python构建系统的编译选项的不同而变化。

导入模块时,Python会依赖一个路径列表。这个列表存储在sys.path变量中,并且告诉Python去哪里搜索要加载的模块。可以在代码中修改这个列表,根据需要添加或删除路径,也可以通过编写Python代码直接修改环境变量PYTHONPATH。下面的方法几乎是相等的1。

>>> import sys

>>> sys.path.append('/foo/bar')

$ PYTHONPATH=/foo/bar python

>>> import sys

>>> '/foo/bar' in sys.path

True

在sys.path中顺序很重要,因为需要遍历这个列表来寻找请求的模块。

也可以通过自定义的导入器(importer)对导入机制进行扩展。Hy2正是利用的这种技术告诉Python如何导入其他非标准的.py或者.pyc文件的。

顾名思义,导入钩子机制是由PEP 302(http://www.python.org/dev/pep...)定义的3。它允许扩展标准的导入机制,并对其进行预处理,也可以通过追加一个工厂类到sys.path_hooks来添加自定义的模块查找器(finder)。

模块查找器对象必须有一个返回加载器对象的find_module(fullname, path=None)方法,这个加载器对象必须包含一个负责从源文件中加载模块的load_module(fullname)方法。

为了进一步说明,下面给出了Hy利用自定义的导入器导入.hy而不是.py结尾的源文件的方法,见示例2.1。

示例 Hy模块导入器

class MetaImporter(object):

def find_on_path(self, fullname):

fls = ["%s/__init__.hy", "%s.hy"]

dirpath = "/".join(fullname.split("."))

for pth in sys.path:

pth = os.path.abspath(pth)

for fp in fls:

composed_path = fp % ("%s/%s" % (pth, dirpath))

if os.path.exists(composed_path):

return composed_path

def find_module(self, fullname, path=None):

path = self.find_on_path(fullname)

if path:

return MetaLoader(path)

sys.meta_path.append(MetaImporter())

一旦路径被确定是有效的且指向了一个模块,就会返回一个MetaLoader对象。

Hy模块加载器

class MetaLoader(object):

def __init__(self, path):

self.path = path

def is_package(self, fullname):

dirpath = "/".join(fullname.split("."))

for pth in sys.path:

pth = os.path.abspath(pth)

composed_path = "%s/%s/__init__.hy" % (pth, dirpath)

if os.path.exists(composed_path):

return True

return False

def load_module(self, fullname):

if fullname in sys.modules:

return sys.modules[fullname]

if not self.path:

return

sys.modules[fullname] = None

mod = import_file_to_module(fullname, self.path)

ispkg = self.is_package(fullname)

mod.__file__ = self.path

mod.__loader__ = self

mod.__name__ = fullname

if ispkg:

mod.__path__ = []

mod.__package__ = fullname

else:

mod.__package__ = fullname.rpartition('.')[0]

sys.modules[fullname] = mod

return mod

import_file_to_module读取一个Hy源文件,将其编译成Python代码,并返回一个Python模块对象。

uprefix模块(https://pypi.python.org/pypi/...)是这个功能起作用的另一个好的例子。Python 3.0到3.2并没有像Python 2中用来表示Unicode字符串的u前缀4,这个模块通过在编译前删除字符串的前缀u 来确保在2.x和3.x之间的兼容性。

摘自书中,希望对你有帮助

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值