如何实现类似NumPy的Python包导入方式——直接导入包文件夹名即可访问内部函数
Great question! The key to making your package behave like NumPy (where import mypackage gives direct access to your functions) lies in leveraging the __init__.py file in your package directory. This file acts as the "entry point" for your package and defines what gets exposed to users when they import it.
Here's a step-by-step guide to achieve this:
1. Keep Your Folder Structure
First, maintain your existing package structure—it's already on the right track:
mypackage/ __init__.py package.py
2. Define Your Functions in package.py
Let's say package.py has some example functions:
# package.py def calculate(x): return x * 2 def greet(name): return f"Hello, {name}!"
3. Modify __init__.py to Expose Functions
The __init__.py file controls what's accessible from the top-level mypackage namespace. You have a few options here, depending on how you want users to interact with your package:
Option A: Explicitly Import Specific Functions (Recommended)
This is the cleanest approach, as it makes it clear exactly what's available at the top level. Add this to __init__.py:
# __init__.py from .package import calculate, greet
Now, when users run import mypackage, they can call your functions directly:
import mypackage print(mypackage.calculate(10)) # Output: 20 print(mypackage.greet("Alice")) # Output: Hello, Alice!
Option B: Import All Functions (With Guardrails)
If you want to expose all functions from package.py without listing them individually, use from .package import *—but pair it with a __all__ list in package.py to avoid exporting unintended names.
First, add __all__ to package.py:
# package.py __all__ = ["calculate", "greet"] # List exactly what should be exported def calculate(x): return x * 2 def greet(name): return f"Hello, {name}!" def _internal_helper(): # This won't be exported because it's not in __all__ pass
Then update __init__.py:
# __init__.py from .package import *
This achieves the same result as Option A, but keeps your __init__.py concise if you have many functions.
Option C: Expose the Submodule (Like NumPy's Submodules)
If you want users to also access mypackage.package.calculate while still having top-level access, import the submodule into __init__.py:
# __init__.py from . import package from .package import calculate, greet
Now users can choose either approach:
import mypackage mypackage.calculate(10) # Works mypackage.package.calculate(10) # Also works
4. Bonus: Install Your Package System-Wide
To make your package accessible anywhere on your system (just like NumPy), create a pyproject.toml file in the parent directory of mypackage:
# pyproject.toml [build-system] requires = ["setuptools>=61.0"] build-backend = "setuptools.build_meta" [project] name = "mypackage" version = "0.1.0"
Then install it using pip:
pip install .
Now you can import mypackage from any script on your machine.
Note: If you wanted import package to work directly, that would require package.py to be in your script's directory or Python path—but that's not a standard package structure. The NumPy-style approach is to import the package folder name (mypackage) and access functions from there, which is what we've set up.
内容的提问来源于stack exchange,提问作者zltn.guba

