python 模块和包的理解
模块
在python中, 模块只是简单的以.py
结尾的源文件, 他们可以位于任何python可以找到的地方
一般导入一个模块,该模块的路径可以是当前目录或者sys.path中的一个环境目录, 我们可以import sys print sys.path
来查看下环境目录都有那些:
['', '/usr/lib/python2.7', '/usr/lib/python2.7/plat-x86_64-linux-gnu', '/usr/lib/python2.7/lib-tk', '/usr/lib/python2.7/lib-old', '/usr/lib/python2.7/lib-dynload', '/usr/local/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages']
第一个空格表示当前目录, 一个标准库和官方模块一般会被安装在/usr/lib/pyhon2.7
目录和/usr/lib/python2.7/dist-packages
, 通过pip安装的第三方模块会被安装在/usr/local/lib/python2.7/dist-packages
模块的导入是有顺序的, 当前目录始终是排在第一位被导入,因此如果你不小心在当前目录下新建一个和标准库重名的模块, 将导致标准库用不了, 这点尤其要注意
内置模块
python 中有一些模块和方法,属性是在python启动是就会加载进内存的,我们可以通过dir()来查看:
>>> dir()
['__builtins__', '__doc__', '__name__', '__package__']
所有的内置函数包括__doc__
,__name__
,__package__
都可以在dir(__builtins__)
中找到
>>> dir(__builtins__)
['ArithmeticError', 'AssertionError', 'AttributeError', 'BaseException', 'BufferError', 'BytesWarning', 'DeprecationWarning', 'EOFError', 'Ellipsis', 'EnvironmentError', 'Exception', 'False', 'FloatingPointError', 'FutureWarning', 'GeneratorExit', 'IOError', 'ImportError', 'ImportWarning', 'IndentationError', 'IndexError', 'KeyError', 'KeyboardInterrupt', 'LookupError', 'MemoryError', 'NameError', 'None', 'NotImplemented', 'NotImplementedError', 'OSError', 'OverflowError', 'PendingDeprecationWarning', 'ReferenceError', 'RuntimeError', 'RuntimeWarning', 'StandardError', 'StopIteration', 'SyntaxError', 'SyntaxWarning', 'SystemError', 'SystemExit', 'TabError', 'True', 'TypeError', 'UnboundLocalError', 'UnicodeDecodeError', 'UnicodeEncodeError', 'UnicodeError', 'UnicodeTranslateError', 'UnicodeWarning', 'UserWarning', 'ValueError', 'Warning', 'ZeroDivisionError', '_', '__debug__', '__doc__', '__import__', '__name__', '__package__', 'abs', 'all', 'any', 'apply', 'basestring', 'bin', 'bool', 'buffer', 'bytearray', 'bytes', 'callable', 'chr', 'classmethod', 'cmp', 'coerce', 'compile', 'complex', 'copyright', 'credits', 'delattr', 'dict', 'dir', 'divmod', 'enumerate', 'eval', 'execfile', 'exit', 'file', 'filter', 'float', 'format', 'frozenset', 'getattr', 'globals', 'hasattr', 'hash', 'help', 'hex', 'id', 'input', 'int', 'intern', 'isinstance', 'issubclass', 'iter', 'len', 'license', 'list', 'locals', 'long', 'map', 'max', 'memoryview', 'min', 'next', 'object', 'oct', 'open', 'ord', 'pow', 'print', 'property', 'quit', 'range', 'raw_input', 'reduce', 'reload', 'repr', 'reversed', 'round', 'set', 'setattr', 'slice', 'sorted', 'staticmethod', 'str', 'sum', 'super', 'tuple', 'type', 'unichr', 'unicode', 'vars', 'xrange', 'zip']
包
模块提供了一个很有用的包装方法来封装小数量的源文件用于复用,但不能完全满足更大的项目, 因此python提供了包(package) 的概念.
一个包的本质是包含很多模块的文件夹,唯一的要求是文件夹必须包含一个名位__init__.py
文件, 对于用户来说包和模块没有很大的区别
有意思的sys 模块和builtin模块
python 中有两个有意思的内建模块,如果你导入后help以下发现file路径为(built-in)
, sys.path的所偶路径下也确实没有找到对应的文件, 更奇怪的是在python的内置空间中并没有这两个模块, 其实这两个模块是隐式的被调用了
__builtin__
:
__builtins__
其实是对__builtin__
模块的引用,并不存在__builtins__
这个模块,我们可以来验证
>>> __builtins__
<module '__builtin__' (built-in)>
类似c,函数名称都在builtins中声明(头文件),但函数定义和实现都是在builtin模块中声明(.c文件)
在Python中并没有builtins这个模块,只有builtin模块,builtins模块只是在启动Python解释器时,解释器为我们自动创建的一个到builtin模块的引用
sys
sys 下有很多有意思的属性,比如sys.path
, sys.modules
, ``builtin_module_names`
sys.path
: 这个属性我们之前说过,记录了python模块的访问路径
sys.modules
: sys.modules是一个全局字典,该字典是python启动后就加载在内存中。每当程序员导入新的模块,sys.modules都将记录这些模块。字典sys.modules对于加载模块起到了缓冲的作用。当某个模块第一次导入,字典sys.modules将自动记录该模块。当第二次再导入该模块时,python会直接到字典中查找,从而加快了程序运行的速度。 默认大小是44, 这些只是sys内建模块导入的库,并不再当前的内置空间中
>>> import sys
>>> len(sys.modules)
44
sys.builtin_module_names
: 暂时没有搞懂和sys.modules的区别
注意内建模块并不会自动加载进当前的名称空间中,还是需要显式的来导入才行, 但builtin因为有一个引用导入到名称空间中,因此builtin模块中的方法可以直接使用,但不能直接使用该模块名