【问题标题】:How create a __len__ function on __init__?如何在 __init__ 上创建 __len__ 函数?
【发布时间】:2012-10-22 13:07:22
【问题描述】:

如何删除此对象中的__size 属性?

class Object():
    def __init__(self, size):
        self.__size = size

    def __len__(self):
        return self.__size

init 函数如何创建 len 函数? Lambda 函数?

PS:在我的实际情况中,我在这个 len 函数中需要做一些计算,但是在实例化之后结果总是相同的(例如元组)。将此结果保存在没有任何隐藏属性的函数中可能会很棒。

【问题讨论】:

  • 你能再具体一点吗?伪私有属性往往是记忆对象中数据的最佳方式,但您的问题有点含糊,无法提供更好的建议。
  • 就像现在一样,没有什么问题,不过我会打电话给会员_sizeExplicit is better than implicit.
  • 简而言之:您不应该为删除该属性而苦苦挣扎。这种方式比较好。

标签: python object python-3.x python-2.7


【解决方案1】:

我不建议这样做,但您可以使用简单的 lambda 函数

class Object():
    def __init__(self, size):
        self.__len__ = lambda: size


>>> len(Object(3))
3

我不建议这样做的原因归结为 Python 之禅:显式优于隐式。简单胜于复杂。

如果您使用的是实例变量,那么它是显式的,您有更好的错误堆栈跟踪,您可以在 __len__ 函数中使用 doctests,并且代码在阅读和更新时更容易理解。

【讨论】:

  • 在 99.9% 的情况下,它会在不添加功能的情况下引入开销。
  • @recursive 显式优于隐式。简单胜于复杂。如果您使用的是实例变量,那么它是显式的,您有更好的错误堆栈跟踪,您可以在 len 函数中使用文档测试,并且代码在阅读和更新时更容易理解。跨度>
  • 这不适用于 Python 3.x。给出错误TypeError: object of type 'Object' has no len()ideone.com/ugAT8k
  • 新式类中的 2.x 也没有。
  • 是否必须改为lambda self: size?认为大多数代码期望 len 是一个实例方法。
【解决方案2】:

因为不可能让__len__ 成为实例属性以便通过len() 使用,所以您必须在类中定义它。但是由于没有其他限制,您可以定义一个实例属性__len__,这样您的命名空间就不会被污染。

class MyObject(object):
    def __init__(self, size):
        self.__len__ = lambda: size
    def __len__(self):
        return self.__len__()

这看起来令人困惑(并且因此可能会受到反对),但它确实有效。

之所以有效,是因为类属性__len__(),即def-ed 函数,调用实例属性__len__(),它是来自__init__() 的lambda。

在展示了可能的情况后,我不推荐它,因为它可能会非常令人困惑。

您原来的解决方案要好得多。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-10-02
    • 1970-01-01
    • 2016-10-03
    • 1970-01-01
    • 2022-08-16
    • 2018-01-03
    • 1970-01-01
    相关资源
    最近更新 更多