5. 北京/上海/??广州 0xFF Life's pathetic, go Pythonic!
relative_import
代码?示例:
from .foo import bar?
from ..foo import bar
? 在 py2.7 之前是python的默认的module引?入?方式
? 推荐阅读:PEP0328
6. 北京/上海/??广州 0xFF Life's pathetic, go Pythonic!
absolute Import
代码?示例:
from __future__ import absolute_import
from API.foo import bar
from API.API2.foo import bar
? 在py2.5实现,需要明确的声明从 __future__ 中引?入该机制。在py2.7和
py3中成为默认的引?入机制。
11. 北京/上海/??广州 0xFF Life's pathetic, go Pythonic!
?小知识:加载python的?二
种?方式
? as the top-level script?
python foo/my?le.py
? as a module:?
python -m foo.my?le
12. 北京/上海/??广州 0xFF Life's pathetic, go Pythonic!
?二种加载?方式的不同之
处
When a ?le is loaded, it is given a name (which is
stored in its __name__ attribute). If it was loaded as
the top-level script, its name is __main__. If it was
loaded as a module, its name is the ?lename,
preceded by the names of any packages/
subpackages of which it is a part, separated by dots.
? 推荐阅读:http://stackover?ow.com/questions/
14132789/pythonrelative-imports-for-the-billionth-
time
14. 北京/上海/??广州 0xFF Life's pathetic, go Pythonic!
出错的原因
? 当使?用?用python subpackage1/foo.py时,foo.py 被当成了
top level script,它的__name__属性被设置为__main__。
? relative import则是根据__name__来确定被引?入?入包的位
置。
Relative imports use a module's __name__ attribute to
determine that module's position in the package hierarchy. If
the module’s name does not contain any package
information (e.g. it is set to '__main__') then relative imports
are resolved as if the module were a top level module,
regardless of where the module is actually located on the ?le
system.
39. 北京/上海/??广州 0xFF Life's pathetic, go Pythonic!
?ask 实现
def load_module(self, fullname):
if fullname in sys.modules:
return sys.modules[fullname]
modname = fullname.split('.', self.prefix_cutoff)[self.prefix_cutoff]
for path in self.module_choices:
realname = path % modname
try:
__import__(realname)
except ImportError:
exc_type, exc_value, tb = sys.exc_info()
sys.modules.pop(fullname, None)
if self.is_important_traceback(realname, tb):
reraise(exc_type, exc_value, tb.tb_next)
continue
module = sys.modules[fullname] = sys.modules[realname]
if '.' not in modname:
setattr(sys.modules[self.wrapper_module], modname, module)
return module
raise ImportError('No module named %s' % fullname)
40. 北京/上海/??广州 0xFF Life's pathetic, go Pythonic!
Hook Example5
>>> import requests
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: No module named ‘requests'
>>> import autoinstall
>>> import requests
Installing requests
>>> requests
<module 'requests' from '...python3.4/site-packages/requests/
__init__.py’>
在import第三?方包时,?自动安装相应的依赖
41. 北京/上海/??广州 0xFF Life's pathetic, go Pythonic!
import sys
import subprocess
import importlib.util
class AutoInstall(object):
_loaded = set()
@classmethod
def find_spec(cls, name, path, target=None):
if path is None!and name not in! cls._loaded:
cls._loaded.add(name)
print("Installing",! name)
try:
out = subprocess.check_output(
[sys.executable, '-m', 'pip', 'install', name])
return importlib.util.find_spec(name)
except Exception as e:
print("Failed")
return None
sys.meta_path.append(AutoInstall)
42. 北京/上海/??广州 0xFF Life's pathetic, go Pythonic!
Refrences
? Modules and Packages:Live and Let Die! —David Beazley
? http://stackover?ow.com/questions/14132789/pythonrelative-imports-for-the-billionth-time
? https://github.com/tornadoweb/tornado
? https://github.com/mitsuhiko/?ask
? PEP 0328
? PEP 0273
? PEP 0338
? PEP 0008
? PEP 0302
? PEP 0366
? PEP 0451