如何实现仅允许在指定类内部实例化的Python类?
解决方案
要实现仅允许在Water类方法内实例化Fish的需求,可以通过Python的inspect模块追踪调用栈,在Fish的构造方法中校验调用上下文。
实现代码
import inspect class Fish: def __init__(self): # 获取调用栈,跳过当前Fish.__init__的帧 stack = inspect.stack() if len(stack) < 2: raise PermissionError("Fish只能在Water类的方法内部实例化") # 获取上层调用帧(即调用Fish()的代码所在的帧) caller_frame = stack[1] # 尝试获取调用方法的self对象 caller_self = caller_frame[0].f_locals.get('self') # 校验调用者是否是Water类的实例 if not isinstance(caller_self, Water): raise PermissionError("Fish只能在Water类的方法内部实例化") class Water: def __init__(self, animal): pass class Land: def __init__(self, animal): pass # 合法调用 habitat = Water(Fish()) # 非法调用:会抛出PermissionError # habitat = Land(Fish()) # fish = Fish()
代码说明
inspect.stack():获取当前的调用栈信息,每个栈元素包含帧对象、文件名、行号等内容。- 跳过
Fish.__init__自身的栈帧,检查上层调用帧的self对象:如果调用Fish()的代码位于Water类的方法内,那么该方法的self必然是Water的实例。 - 若校验不通过,直接抛出
PermissionError阻止实例化。
扩展说明
如果需要允许在Water类的任意方法(而非仅__init__)中实例化Fish,上述代码已经支持,只要调用代码是Water实例的方法内部即可。
内容的提问来源于stack exchange,提问作者Jan Viljoen
相关产品推荐
相关产品推荐

