You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python内部如何区分from包导入模块与from模块导入函数?

How Python Handles from...import... for Packages vs Modules

Nice question! Let’s break down exactly how Python’s interpreter processes from A import B, and whether it distinguishes between packages and modules upfront.

The Short Answer

Python doesn’t first "check if A is a package or module" as a separate step. Instead, it treats both packages and modules as the same core type of object (a module object)—with just a few extra behaviors for packages. The import process follows a unified flow, with differences emerging only when handling what happens after A is loaded.

Step 1: Loading "A" (Package or Module)

When the interpreter sees from A import B, its first task is to locate and load A using the sys.path search order:

  • If it finds a file named A.py, that’s a regular module. The interpreter loads this file, executes its code, and creates a module object to represent it.
  • If it finds a folder named A (either with an __init__.py file, or a namespace package in Python 3.3+), that’s a package. The interpreter loads the __init__.py file (if it exists) to create a module object—this object just has an extra __path__ attribute that points to the package’s directory (or directories, for namespace packages).

Key point: Run type(A) after importing, and you’ll see <class 'module'> for both packages and regular modules. Packages are just specialized modules.

Step 2: Finding "B" in A’s Namespace

Once A is loaded (as a module object), the interpreter looks for B directly in A’s namespace (stored in A.__dict__):

  • If A is a regular module: B can be any function, class, variable, or imported object defined in A.py. For example:
    from math import sqrt  # sqrt is a function in the math module's namespace
    
  • If A is a package: B can be two things:
    1. An object defined directly in A/__init__.py (like a function or variable).
    2. A sub-module or sub-package inside the A folder. In this case, the interpreter uses A’s __path__ attribute to locate the sub-module (e.g., A/B.py or A/B/__init__.py), loads it, and adds it to A’s namespace. For example:
      from my_package import utils  # utils is a sub-module loaded from my_package/utils.py
      
    Note: If you want to import a function from a sub-module directly (like from my_package import my_func), you need to explicitly import my_func into my_package/__init__.py first—otherwise, the interpreter won’t find it in the package’s top-level namespace.

Extra: What Makes Packages Special?

The only real difference between a package and a regular module is the __path__ attribute:

  • Regular modules don’t have __path__.
  • Packages use __path__ to tell the interpreter where to look for sub-modules and sub-packages.
  • Namespace packages (no __init__.py) have a __path__ that includes multiple directories, letting you split a package across different locations on your filesystem.

Wrap-Up

To recap: When Python processes from A import B, it:

  1. Loads A as a module object (whether it’s a package or regular module).
  2. Looks up B in A’s namespace, with minor differences in how it handles sub-modules if A is a package.

Packages aren’t a separate "type" to the interpreter—they’re just modules with extra tools to manage nested code.

内容的提问来源于stack exchange,提问作者zell

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 07:45:23