【问题标题】:len() vs __len__: TypeError: 'float' object cannot be interpreted as an integerlen() vs __len__: TypeError: 'float' 对象不能被解释为整数
【发布时间】:2021-05-10 11:03:23
【问题描述】:

我遇到了一个奇怪的错误,我认为这不是我的代码的问题。

这是我得到的物品:

  • Boundary:表示域和范围,如[1, 10],它有一个low属性和一个high属性,在本例中为low = 1high=10
  • Lim:表示联合集,如[1, 10]U[20, 30],存储为self.boundaries = [Boundary([1, 10]), Boundary([20, 30])]

这就是我想要做的,

  1. 我在边界中定义了__len__,这样len(Boundary([1, 10])) #=> 9
class Boundary:
    def __len__(self):
            return abs(self.high - self.low)
  1. 在 Lim 对象中,我有self.boundaries,这是一个边界对象列表。定义了边界中的__len__,我将Lim 的__len__ 编码如下:
class Lim:
    def __len__(self):
            return sum([len(bd) for bd in self.boundaries])

以下是问题的发生方式,其组成如下:

class Boundary:
    def __len__(self):
        return abs(self.high - self.low)

class Lim:
    def __len__(self):
        return sum([len(bd) for bd in self.boundaries])

print(len(Lim([1, 10], [20, 30])))

# Traceback (most recent call last):
#   File "boundary.py" in <module>
#     print(len(Lim([1, 10], [20, 30])))
#   File "boundary.py", in __len__
#     return sum([len(bd) for bd in self.boundaries])
#   File "boundary.py", in <listcomp>
#     return sum([len(bd) for bd in self.boundaries])
# TypeError: 'float' object cannot be interpreted as an integer

但是有了这个组合:

class Boundary:
    def __len__(self):
        return abs(self.high - self.low)

class Lim:
    def __len__(self):
        return sum([bd.__len__() for bd in self.boundaries])

print(len(Lim([1, 10], [20, 30])))

# Traceback (most recent call last):
#   File "boundary.py",in <module>
#   print(len(Lim([1, 10], [20, 30])))
# TypeError: 'float' object cannot be interpreted as an integer

但是,代码最终以这种组合执行:

class Boundary:
    def __len__(self):
        return abs(self.high - self.low)

class Lim:
    def __len__(self):
        return sum([bd.__len__() for bd in self.boundaries])

print(Lim([1, 10], [20, 30]).__len__())
# 19

为什么将len() 更改为__len__() 会消除错误?如果你能提供一些帮助,我会很高兴。

【问题讨论】:

  • 这里已经回答了这个问题:stackoverflow.com/a/2481433/2402281
  • @tahesse 对不起,我之前读过一些相关的帖子,但没有解决我的问题
  • 很公平。您介意与我们分享您的LimBoundary 构造函数吗?我会为你起草一个演示。
  • 发布的代码不会给出发布的输出。即使填写合理的__init__ 方法,也不会给出贴出的输出。 tahesse 关于潜在错误的原因很可能是正确的,但问题中的代码没有重现错误。
  • __len__ 旨在检索序列和其他集合的大小 - 具有离散、整数大小的事物,通常受内存限制。尽管有这个名字,但它不适用于线段和曲线的长度,或者区间的大小,或者返回值需要为非整数的其他用例。

标签: python sum typeerror magic-methods variable-length


【解决方案1】:

正如 cmets 中所指出的,len 与您的用例不兼容。我不知道您的解决方案需要多么灵活,但我想出了一个最低限度的工作示例:

from typing import List

def dist(boundary: object, m='euclidean') -> float:
    """Computes a given distance for object-typed boundaries.
    """
    return boundary.__dist__(m)

def converge(lim: object) -> float:
    """_Integrates_ the distances over boundaries."""
    return lim.__converge__()


class Boundary(object):
    low = 0
    high = 0
    
    def __init__(self, lo: float, hi: float):
        self.low = lo
        self.high = hi
        
    def __dist__(self, m: str) -> float:
        if m == 'euclidean':
            return abs(self.high - self.low)
        else:
            raise Error(f'Unknown distance {m}')

class Lim(object):
    boundaries = []
    def __init__(self, boundaries: List[Boundary]):
        self.boundaries = boundaries

    def __converge__(self) -> float:
        return sum([dist(bd) for bd in self.boundaries])

print(converge(Lim([Boundary(1.0, 10.0), Boundary(20.0, 30.0)])))
# expect abs(10-1) + abs(30-20) = 9+10 = 19

这就是你想要的(据我所知)。此外,您可以引入基于Boundary 类的不同Boundary 类。对于Boundary 基类,您可以引入不同的距离度量,对于Lim 类(作为基类),您可以创建不同的收敛方案。虽然这个答案没有对您最初的问题提出一点意见(全部都在 cmets 中),但这是否以某种方式为您勾勒出前进的方向?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-14
    相关资源
    最近更新 更多