函数表达式可通过闭包和作用域隔离模拟私有方法:将内部函数定义在外部函数中,仅返回受限接口,不暴露实现细节,如create_counter()和create_bank_account()所示;单下划线前缀是约定而非强制保护,双下划线在函数中无效。

函数表达式本身不直接支持“私有方法”这个面向对象概念,因为它是过程式或函数式风格的写法,没有类(class)结构。但你可以通过闭包和作用域隔离模拟出类似私有方法的效果——即把某些逻辑封装在内部,不暴露给外部调用。
用闭包隐藏内部函数
这是最常用也最自然的方式:把“私有函数”定义在外部函数内部,只通过返回的函数间接使用它。
- 外部函数创建局部变量和内部函数
- 内部函数引用这些变量(构成闭包)
- 外部函数只返回需要公开的接口,不返回内部函数本身
示例:
def create_counter():
count = 0
def increment(): # 这个函数对外不可见,相当于“私有”
nonlocal count
count += 1
return count
def reset(): # 同样是内部实现细节
nonlocal count
count = 0
return lambda: increment() # 只暴露一个调用方式
<p>counter = create_counter()
print(counter()) # 1
print(counter()) # 2</p><h1>increment() 和 reset() 无法从外部直接调用 → 实现了“私有”效果</h1><p>工厂函数中返回受限接口
进一步封装,可返回一个字典或简单对象,只包含你允许调用的方法,把真正干活的函数留在闭包内。
- 所有核心逻辑(如验证、计算、状态更新)都放在闭包内部
- 返回的接口函数只是“门面”,不泄露实现
- 外部无法绕过接口直接访问底层函数
示例:
def create_bank_account(initial=0):
balance = initial
def _validate(amount): # “下划线前缀”约定为内部使用
return isinstance(amount, (int, float)) and amount >= 0
def deposit(amount):
if _validate(amount):
nonlocal balance
balance += amount
return balance
raise ValueError("非法金额")
def get_balance():
return balance
return {"deposit": deposit, "balance": get_balance}
<p>acct = create_bank_account(100)
print(acct["balance"]()) # 100
acct<a href="https://www.php.cn/link/709468cc3418b6363cbd2557759e9344">"deposit"</a>
print(acct["balance"]()) # 1https://www.php.cn/link/709468cc3418b6363cbd2557759e9344</p><h1>_validate 无法从 acct 外部访问 → 事实上的私有方法</h1><p>避免用双下划线命名函数表达式
在纯函数式写法中,不要对普通函数加 __name__ 形式命名,因为 Python 的名称修饰(name mangling)只在 class 内生效。函数表达式里写 def __helper() 不会触发修饰,只是普通函数,且容易误导他人以为有访问控制。
- __开头在模块顶层或函数内无特殊含义,不提供任何保护
- 想“私有”,靠的是作用域隔离,不是命名规则
- 若真需强调内部性,可用单下划线前缀(如
_helper),这是通用约定
对比类中的私有方法
类里用 def __method(self) 是语法糖,本质靠名称修饰(变成 _ClassName__method)实现软性隔离;而函数表达式没有类上下文,所以必须依赖闭包和作用域来达成同等目的。
- 类私有:靠解释器重命名 + 约定不调用
- 函数表达式“私有”:靠变量未导出 + 函数未返回 + 作用域封闭
- 两者都不是强制访问限制,但后者更轻量、更函数式

















