Python中如何在执行类方法前获取方法入参并进行修改

请教个问题,感谢~ 问题:C1 类如何改动,调用 c1.swimming()时 等同于 调用 c1.swimming(c1.add_punctuation( ))。


class C(object):
    def __init__(self):
        self.name = 'zhangsan '
def swimming(self, action):
    return self.name + action

class C1©: def add_punctuation(self, text): return ‘:’ + text

c1 = C1() print c1.swimming(c1.add_punctuation(‘swimming’)) # >zhangsan :swimming print c1.swimming(‘swimming’) # >zhangsan swimming


Python中如何在执行类方法前获取方法入参并进行修改

8 回复

inspect package
functools.partial


在Python里,要在执行类方法前获取并修改入参,最直接的方式是使用装饰器或者重写类的__getattribute__方法。不过,__getattribute__会拦截所有属性访问,用起来比较重,通常更推荐用装饰器,这样更清晰、更可控。

下面我给你写个装饰器的例子,它能在方法执行前打印出入参,并且还能让你修改这些参数:

import functools

def intercept_and_modify_args(func):
    """
    一个装饰器,用于在方法执行前拦截并修改其入参。
    """
    @functools.wraps(func)
    def wrapper(self, *args, **kwargs):
        # 1. 获取原始入参
        print(f"方法 '{func.__name__}' 被调用。")
        print(f"  原始位置参数: {args}")
        print(f"  原始关键字参数: {kwargs}")

        # 2. 在这里你可以修改参数
        # 例如,我们把所有位置参数都转成字符串,并给关键字参数加个前缀
        modified_args = [str(arg) for arg in args]
        modified_kwargs = {f"modified_{key}": value for key, value in kwargs.items()}

        print(f"  修改后的位置参数: {modified_args}")
        print(f"  修改后的关键字参数: {modified_kwargs}")

        # 3. 用修改后的参数调用原方法
        return func(self, *modified_args, **modified_kwargs)
    return wrapper

class MyClass:
    @intercept_and_modify_args
    def my_method(self, a, b, name=None):
        print(f"  方法内部执行: a={a}, b={b}, name={name}")
        return f"Result: {a}, {b}, {name}"

# 测试一下
obj = MyClass()
result = obj.my_method(42, 3.14, name="Alice")
print(f"最终结果: {result}")

运行这段代码,你会看到类似这样的输出:

方法 'my_method' 被调用。
  原始位置参数: (42, 3.14)
  原始关键字参数: {'name': 'Alice'}
  修改后的位置参数: ['42', '3.14']
  修改后的关键字参数: {'modified_name': 'Alice'}
  方法内部执行: a=42, b=3.14, name=Alice
最终结果: Result: 42, 3.14, Alice

这个装饰器intercept_and_modify_args干了三件事:1)拿到原始参数;2)按你的需求改参数(例子里是把位置参数转字符串、给关键字参数加前缀);3)用改好的参数去调原方法。你只要把它加到想拦截的方法上就行,比如用@intercept_and_modify_args装饰my_method

如果你需要对一个类里的所有方法都这么处理,可以考虑用类装饰器或者元类,但那样会复杂不少。对于大多数情况,单个方法加装饰器就够用了,简单又灵活。

总结:用装饰器来拦截和修改方法入参最靠谱。

感谢回复!!抱歉我的问题可能没说清楚。我想实现的效果是:
python<br><br>c1.swimming(c1.add_punctuation('swimming'))<br>c1.swimming('swimming')<br>#他们调用时等同<br><br>

那就在 C1 里面 override swimming 函数就行了

感谢你的回复。目前遇到的问题是 C 是工具类,内部有很多方法。C1 继承 C,C1 是调用类,使用 C1 调用 C 方法,参数必须需要处理一下。override 是不是太复杂了,因为 C 有很多方法

你要做的就是修改 swimming 的实现,使用 override 不是最简单的么,看不出哪里复杂:
def swimming(self, action):
return C.swimming(self, self.add_punctuation(action)) # 或者 return super(C1, self).swimming(self.add_punctuation(action))

如果你有一堆方法需要修改参数,先写一个 decorator,用处是计算并传递新参数;然后再写个 metaclass,对满足要求的方法都应用上这个 decorator。

因为你写的例子里面,override 是可行的。
但是在真正的项目里面复杂很多,所以你可以考虑下 override getattribute 这个函数。


非常感谢两位,提供思路!!

回到顶部