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

__repr__装饰器在子类中失效的原因及修复方法咨询

Why does inheriting from the Container class decorated with __repr__dec trigger a TypeError?

Let's break down the issue and fix it step by step.

The Root Cause

Chances are your __repr__dec decorator has a critical flaw in how it defines the replacement __repr__ method: it doesn't include the required self parameter for instance methods.

When you decorate a class with your decorator, it replaces the class's __repr__ with a function that doesn't accept an instance argument. Then, when you create a subclass and try to call __repr__ on its instance, Python automatically passes the instance as the first argument to the method—but your decorated __repr__ can't handle that, hence the TypeError (you'll usually see a message like "new_repr() takes 0 positional arguments but 1 was given").

Another less common scenario is if your decorator replaces the original class entirely (e.g., returns a new subclass of the original) without properly preserving metadata or handling metaclasses, but the missing self parameter is far more likely.

How to Fix It

We need to adjust the decorator to generate a valid instance method, and also make it subclass-friendly. Here's a corrected implementation:

import functools

def __repr__dec(cls):
    # Optional: Preserve the original __repr__ in case we need it later
    original_repr = cls.__repr__
    
    @functools.wraps(original_repr)
    def new_repr(self):
        # Collect all instance attributes, using !r to get proper repr formatting for values
        attr_str = ", ".join(f"{key}={value!r}" for key, value in self.__dict__.items())
        # Use self.__class__.__name__ to ensure subclasses show their own class name
        return f"{self.__class__.__name__}({attr_str})"
    
    # Replace the class's __repr__ with our improved version
    cls.__repr__ = new_repr
    return cls

Key Improvements:

  • Added self parameter: The new_repr function now accepts the instance argument, making it a valid instance method.
  • Subclass-friendly naming: Using self.__class__.__name__ instead of hardcoding the parent class name means subclasses will display their own class name in the repr output, not just Container.
  • Preserved metadata: functools.wraps copies over metadata from the original __repr__ (like docstrings and method names), which avoids subtle compatibility issues.
  • Better value formatting: Using value!r ensures each attribute's value uses its own __repr__ for consistent, Pythonic output.

Test It Out

With this corrected decorator, inheritance works as expected:

@__repr__dec
class Container:
    def __init__(self, x):
        self.x = x

class SubContainer(Container):
    def __init__(self, x, y):
        super().__init__(x)
        self.y = y

# Test parent class
c = Container(42)
print(c)  # Output: Container(x=42)

# Test subclass
sc = SubContainer(10, "hello world")
print(sc)  # Output: SubContainer(x=10, y='hello world')

No more TypeError, and the repr output works correctly for both parent and child classes.


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 08:10:17