重写自定义 Python 类中的默认方法的简单方法?

发布于 2024-09-18 23:44:19 字数 994 浏览 5 评论 0原文

我有一个名为 Cell 的类:

class Cell:

    def __init__(self, value, color, size):
        self._value = value
        self._color = color
        self._size = size

    # and other methods...

Cell._value 将存储字符串、整数等(无论我使用该对象做什么)。我希望所有通常使用对象“值”的默认方法都可以使用 ._value 这样我就可以做到:

>>> c1 = Cell(7, "blue", (5,10))
>>> c2 = Cell(8, "red", (10, 12))
>>> print c1 + c2
15

>>> c3 = Cell(["ab", "cd"], "yellow", (50, 50))
>>> print len(c3), c3
2 ['ab', 'cd']

# etc.

我可以覆盖所有默认方法:

class Cell:

    def __init__(self, value, color, size):
        # ...

    def __repr__(self):
        return repr(self._value)

    def __str__(self):
        return str(self._value)

    def __getitem__(self, key):
        return self._value[key]

    def __len__(self):
        return len(self._value)

    # etc.

...但是有更简单的方法吗?

I have a class called Cell:

class Cell:

    def __init__(self, value, color, size):
        self._value = value
        self._color = color
        self._size = size

    # and other methods...

Cell._value will store a string, integer, etc. (whatever I am using that object for). I want all default methods that would normally use the "value" of an object to use <Cell object>._value so that I can do:

>>> c1 = Cell(7, "blue", (5,10))
>>> c2 = Cell(8, "red", (10, 12))
>>> print c1 + c2
15

>>> c3 = Cell(["ab", "cd"], "yellow", (50, 50))
>>> print len(c3), c3
2 ['ab', 'cd']

# etc.

I could override all the default methods:

class Cell:

    def __init__(self, value, color, size):
        # ...

    def __repr__(self):
        return repr(self._value)

    def __str__(self):
        return str(self._value)

    def __getitem__(self, key):
        return self._value[key]

    def __len__(self):
        return len(self._value)

    # etc.

...but is there an easier way?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

不回头走下去 2024-09-25 23:44:19

如果我理解正确,您正在寻找一种简单的方法将对象的方法委托给该对象的属性?

您可以通过定义装饰器来避免一些重复性:

def delegate(method, prop):
    def decorate(cls):
        setattr(cls, method,
            lambda self, *args, **kwargs:
                getattr(getattr(self, prop), method)(*args, **kwargs))
        return cls
    return decorate

然后您可以为要委托的每个方法应用装饰器:

@delegate('__len__', '_content')
@delegate('__getitem__', '_content')
class MyList(object):
    def __init__(self, content):
        self._content = content

spam = MyList([1,2,3,4,5])

len(spam) # prints "5"

spam[0] # prints "1"

您可以通过修改装饰器以将多个方法名称作为参数来进一步简化它。

如果您希望您的类充当完整的包装器,您可能可以重写该类的 __getattr__ 方法以在失败之前检查包装的对象。这将在没有实际继承的情况下模拟子类的行为。

If I understand you correctly, you're looking for an easy way to delegate an object's method to a property of that object?

You can avoid some of the repetitiveness by defining a decorator:

def delegate(method, prop):
    def decorate(cls):
        setattr(cls, method,
            lambda self, *args, **kwargs:
                getattr(getattr(self, prop), method)(*args, **kwargs))
        return cls
    return decorate

You can then apply the decorator for each method you want delegated:

@delegate('__len__', '_content')
@delegate('__getitem__', '_content')
class MyList(object):
    def __init__(self, content):
        self._content = content

spam = MyList([1,2,3,4,5])

len(spam) # prints "5"

spam[0] # prints "1"

You could probably simplify it further by modifying the decorator to take multiple method names as argument.

If you want your class to act as a full wrapper, you could probably override the class's __getattr__ method to check the wrapped object before failing. That would emulate the behaviour of subclasses without actual inheritance.

笙痞 2024-09-25 23:44:19

您需要重载 __add__ 方法才能获得您想要的 c1 + c2 行为。

有关它们的详细信息,请参阅此处

You need to overload the __add__ method in order to get the c1 + c2 behavior you want.

See here for info on what they all are.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文