Python3 模块

import 语法、模块查找路径、__name__ 属性、dir() 函数、标准模块与包。

Beginner
Key Pointsimport 导入整个模块、from 导入具体名字;__name__ 区分「被导入」与「直接运行」;包就是带 __init__.py 的目录。

import 语句

import module loads the whole module and you reach into it with module.name. This keeps namespaces explicit and avoids clashes; as gives a short alias.

Python
import math
import random as rnd

print(math.sqrt(9))
print(math.pi)

print(rnd.randint(1, 3) in (1, 2, 3))
print(rnd.__name__)
Output
3.0
3.141592653589793
True
random

from … import 语句

from module import name pulls in just the names you need so you can use them unqualified. The trade-off is unclear provenance and possible clashes, so import sparingly.

Python
from math import sqrt, pi

print(sqrt(16))
print(pi)

from collections import Counter

c = Counter('abracadabra')
print(c.most_common(2))
Output
4.0
3.141592653589793
[('a', 5), ('b', 2)]

from … import * 语句

from module import * imports every public name. It makes the namespace unpredictable — you cannot tell what arrived or what it shadowed — so avoid it in production code.

Python
ns = {}
exec('from math import *', ns)
names = sorted(k for k in ns if not k.startswith('__'))
print(len(names) > 20)
print('sqrt' in names, 'pi' in names)
print(names[:3])
Output
True
True True
['acos', 'acosh', 'asin']
import * is only convenient for interactive exploration. If the module defines __all__, only the names listed there are imported.

深入模块

A module is just a .py file whose name (minus extension) is the module name. Top-level code runs once on first import; later imports come from the sys.modules cache.

Python
import sys
import json

print('json' in sys.modules)
print(json.__name__)
print(json.__file__.endswith('.py') or json.__file__.endswith('.pyc'))

print(len(sys.path) > 0)
print(type(sys.modules).__name__)
Output
True
json
True
True
dict

__name__ 属性

Every module has __name__: the module name when imported, '__main__' when run as a script. That is exactly how if __name__ == '__main__': distinguishes the two cases.

Python
print(__name__)
print(__name__ == '__main__')

import math
print(math.__name__)
print(math.__name__ == '__main__')

def main():
    print('running as script')

if __name__ == '__main__':
    main()
Output
__main__
True
math
False
running as script

dir() 函数

dir(module) lists every name the module defines, sorted; with no argument it lists the current scope. It is the fastest way to explore an unfamiliar module.

Python
import math

names = dir(math)
print(len(names) > 30)
print('sqrt' in names, 'pi' in names)
print([n for n in names if n.startswith('is')])

x = 1
print('x' in dir())
Output
True
True True
['isclose', 'isfinite', 'isinf', 'isnan', 'isqrt']
True

标准模块

Python ships a standard library covering files, networking, text, dates and concurrency — importable with no install. Common ones: os, sys, json, re, datetime, collections, itertools, pathlib.

Python
import os
import sys
import json
import re
import datetime
import collections
import itertools
import pathlib

mods = [os, sys, json, re, datetime, collections, itertools, pathlib]
for m in mods:
    print(m.__name__, '->', m.__name__ in sys.modules)
Output
os -> True
sys -> True
json -> True
re -> True
datetime -> True
collections -> True
itertools -> True
pathlib -> True

包

A package is a directory with an __init__.py, grouping related modules hierarchically. Importing pkg.mod first runs pkg/__init__.py, then loads the submodule.

Python
# 目录结构:
# sound/
#   __init__.py
#   formats/
#     __init__.py
#     wavread.py
#     wavwrite.py

import os
import tempfile

root = tempfile.mkdtemp()
pkg = os.path.join(root, 'sound')
os.makedirs(os.path.join(pkg, 'formats'))

for path in (pkg, os.path.join(pkg, 'formats')):
    open(os.path.join(path, '__init__.py'), 'w').close()

print(sorted(os.listdir(pkg)))
print(os.path.exists(os.path.join(pkg, '__init__.py')))
Output
['__init__.py', 'formats']
True
Since Python 3.3 "namespace packages" let a directory without __init__.py be imported. Regular projects should still keep it for clarity and tooling compatibility.

从一个包中导入 *

from pkg import * follows __all__ in the package's __init__.py: if defined, only the listed submodules come in; otherwise every already-loaded submodule does.

Python
# sound/__init__.py 里写:
#   __all__ = ["echo", "surround", "reverse"]

ns = {}
exec("__all__ = ['echo', 'surround', 'reverse']", ns)
print(ns['__all__'])

ns2 = {}
exec("from math import *", ns2)
print('sqrt' in ns2, 'log' in ns2)
Output
['echo', 'surround', 'reverse']
True True

Friends & Partners