如何在Python中复制类对象并移除__call__方法使其不可调用?
解决方案
核心思路
要创建一个与原类完全一致但移除__call__方法的新类,关键是动态生成独立的类对象,而非直接复制或子类化。利用Python的type函数可以直接创建类,通过复制原类的命名空间并排除__call__,就能生成一个完全独立的新类,不会影响原类的任何属性。
代码实现
def duplicate_class_without_call(original_cls): # 复制原类的所有属性,排除__call__方法 filtered_namespace = { attr: value for attr, value in original_cls.__dict__.items() if attr != '__call__' } # 用type动态创建新类:参数依次为类名、基类元组、属性命名空间 new_class = type( original_cls.__name__, original_cls.__bases__, filtered_namespace ) # 同步原类的特殊元数据(如模块、文档字符串) if '__module__' not in filtered_namespace: new_class.__module__ = original_cls.__module__ if '__doc__' not in filtered_namespace: new_class.__doc__ = original_cls.__doc__ return new_class
使用示例
假设原类定义如下:
class ComplexCallableClass: def __call__(self, *args, **kwargs): return "This instance is callable" def core_method(self): return "Core method works" @classmethod def class_level_op(cls): return "Class method works" @staticmethod def static_op(): return "Static method works"
生成无__call__的新类并验证:
# 生成新类 NonCallableClass = duplicate_class_without_call(ComplexCallableClass) # 验证原类不受影响 assert hasattr(ComplexCallableClass, '__call__') assert ComplexCallableClass()() == "This instance is callable" # 验证新类无__call__且不可调用 assert '__call__' not in NonCallableClass.__dict__ try: NonCallableClass()() except TypeError: print("实例不可调用,符合预期") # 验证其他方法完全保留 obj = NonCallableClass() assert obj.core_method() == "Core method works" assert NonCallableClass.class_level_op() == "Class method works" assert NonCallableClass.static_op() == "Static method works"
为什么之前的方法失效
copy.deepcopy复制类的问题:Python中类对象属于全局单例,deepcopy对类的默认处理是返回原类的引用,而非创建新的类实例。因此修改复制后的类的属性,本质上是修改原类。- 子类重写
__getattribute__的问题:子类仅能隐藏__call__的访问,但父类的__call__仍存在于类的继承链中。Python调用实例时会直接查找类的__call__方法,子类未重写的话会沿用父类实现,因此实例依然可调用。
内容的提问来源于stack exchange,提问作者mguijarr
相关产品推荐
相关产品推荐

