如何创建可接受任意方法名并打印该方法名的对象?
实现可接受任意方法调用并打印方法名的对象
当然可行啦!这种需求本质是利用编程语言的动态方法/属性拦截特性来实现——不用预先定义任何方法,只要调用对象上的任意名称,都能被捕获并打印出来。我拿两种常用语言给你演示具体实现:
Python 实现
Python 里可以通过 __getattr__ 这个特殊方法来拦截不存在的属性/方法调用:
class MethodPrinter: def __getattr__(self, method_name): # 当调用对象上不存在的方法时,这个方法会自动触发 def method_wrapper(*args, **kwargs): print(f"调用了方法: {method_name}") # 如果需要打印方法参数,取消下面这行注释即可 # print(f"方法参数: 位置参数={args}, 关键字参数={kwargs}") return method_wrapper # 测试一下效果 printer = MethodPrinter() printer.hello() # 输出: 调用了方法: hello printer.ok(123, foo="bar") # 输出: 调用了方法: ok printer.random_method_name() # 输出: 调用了方法: random_method_name
原理说明
__getattr__ 是 Python 的魔法方法之一,只有当你访问对象不存在的属性(包括方法)时,它才会被触发。我们在这个方法里返回了一个包装函数,所以当用户“调用”这个不存在的方法时,实际执行的是我们定义的包装函数,从而实现打印方法名的效果。
JavaScript 实现
JavaScript 可以用 Proxy 对象来实现类似的拦截逻辑:
const methodPrinter = new Proxy({}, { get(target, methodName) { // 拦截属性访问,返回一个函数作为方法 if (typeof methodName === 'string') { return (...args) => { console.log(`调用了方法: ${methodName}`); // 打印参数的话取消下面注释 // console.log(`方法参数:`, args); }; } // 对于非字符串的属性(比如Symbol),返回原对象的属性 return target[methodName]; } }); // 测试 methodPrinter.hello(); // 输出: 调用了方法: hello methodPrinter.ok('test', { key: 'value' }); // 输出: 调用了方法: ok methodPrinter.my_custom_method(); // 输出: 调用了方法: my_custom_method
原理说明
Proxy 是 ES6 引入的对象,它可以创建一个目标对象的代理,拦截并自定义目标对象的各种操作(这里我们拦截了属性访问操作 get)。当用户访问代理对象上的方法名时,get 拦截器会返回一个函数,调用这个函数时就会执行打印方法名的逻辑。
其他编程语言(比如Ruby、PHP)也有类似的特性,核心思路都是拦截不存在的方法调用请求,然后执行自定义逻辑。
内容的提问来源于stack exchange,提问作者John Smith
相关产品推荐
相关产品推荐

