You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

装饰器与带参数继承:如何将子类参数传入继承的装饰器

Solution: Pass Instance Parameter B to the Decorator

Alright, let's work through this problem step by step. First, we'll fix a critical small issue in your original code, then adjust the decorator to properly access the B parameter from your foo instance.

Step 1: Fix the Parent Class Constructor Call

Your foo class inherits from bar, but bar's __init__ requires a val parameter. In your modified code, you're calling bar.__init__(self) without passing val—this will throw a TypeError. We'll use super() to correctly invoke the parent constructor and pass the required val along with your new B parameter.

Step 2: Adjust the Decorator to Access Instance B

Since your decorator wraps an instance method, the inner function of the decorator already receives the foo instance (as obj) as the first argument. This means you can directly access obj.B within the decorator's logic—no need to pass B to the decorator at definition time (since B is an instance-specific value that only exists when a foo object is created).

Complete Working Code

class bar(object):
    def __init__(self, val):
        self.val = val

    @staticmethod
    def decor(func):
        def increment(obj, x):
            # Access both parent class's val and foo instance's B
            return func(obj, x) + obj.val + obj.B
        return increment

class foo(bar):
    def __init__(self, B, val):
        # Correctly call parent constructor with required val parameter
        super().__init__(val)
        self.B = B

    @bar.decor
    def add(self, x):
        return x

# Test the implementation
if __name__ == "__main__":
    # Create a foo instance with B=5 and val=10
    foo_instance = foo(B=5, val=10)
    # Expected result: 3 + 10 +5 = 18
    print(foo_instance.add(3))  # Output: 18

How It Works

  • When you decorate foo.add with @bar.decor, the decorator replaces the original add method with the increment function.
  • When you call foo_instance.add(3), the increment function runs: it calls the original add method (which returns 3), then adds foo_instance.val (10) and foo_instance.B (5) to get the final result.

Alternative: Static B for All Instances

If you wanted B to be a fixed value for all foo instances (instead of instance-specific), you could modify the decorator to accept parameters:

class bar(object):
    def __init__(self, val):
        self.val = val

    @staticmethod
    def decor_with_B(B):
        def actual_decorator(func):
            def increment(obj, x):
                return func(obj, x) + obj.val + B
            return increment
        return actual_decorator

class foo(bar):
    def __init__(self, val):
        super().__init__(val)

    # Use parameterized decorator with fixed B=5
    @bar.decor_with_B(B=5)
    def add(self, x):
        return x

Note that this makes B a static value for all foo instances, which is likely not what you need since you added B as an instance parameter in foo.__init__.

内容的提问来源于stack exchange,提问作者Jackiemiao

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 08:56:20