TypeError: '<' not supported between instances of pyshipping.Package after running 2to3

TypeError: '<' not supported between instances of pyshipping.Package after running 2to3

Python 这里是新手,很有可能我在这里犯了一个愚蠢的错误..

在失去了很多头发并搜索了很多小时之后,我仍然无法将整个项目转换为 python 3. 我有一个用 django 框架制作的项目,它使用 python 3.7,我想将这个库合并到我的应用程序中。但是,因为 pyshipping uses python 2.7, I thought it may cause compatibility issues. Following this 回答,我转换了整个项目并尝试 运行 宁这个文件 binpack_simple.py。但这给了我一个我根本无法理解的错误。当我 运行 这个文件使用我的 pycharm 终端时,当项目 iterpreter 设置为 python 2.7 时,它 运行 是完美的,但是当我将 iterpreter 设置为 3.7 时,它给了我以下错误

return _pyprofile._Utils(Profile).run(statement, filename, sort)
  File "C:\Users\idadarklord\AppData\Local\Programs\Python\Python37\lib\profile.py", line 53, in run
    prof.run(statement)
  File "C:\Users\idadarklord\AppData\Local\Programs\Python\Python37\lib\cProfile.py", line 95, in run
    return self.runctx(cmd, dict, dict)
  File "C:\Users\idadarklord\AppData\Local\Programs\Python\Python37\lib\cProfile.py", line 100, in runctx
    exec(cmd, globals, locals)
  File "<string>", line 1, in <module>
  File "C:/Users/idadarklord/PycharmProjects/untitled/pyshipping/binpack_simple.py", line 230, in test
    bins, rest = binpack(packages)
  File "C:/Users/idadarklord/PycharmProjects/untitled/pyshipping/binpack_simple.py", line 218, in binpack
    return allpermutations(packages, bin, iterlimit)
  File "C:/Users/idadarklord/PycharmProjects/untitled/pyshipping/binpack_simple.py", line 203, in allpermutations
    trypack(bin, todo, bestpack)
  File "C:/Users/idadarklord/PycharmProjects/untitled/pyshipping/binpack_simple.py", line 187, in trypack
    bins, rest = packit(bin, packages)
  File "C:/Users/idadarklord/PycharmProjects/untitled/pyshipping/binpack_simple.py", line 131, in packit
    packages = sorted(originalpackages)
TypeError: '<' not supported between instances of 'Package' and 'Package'

这是我的文件。请让我知道是否应该上传整个项目以进行说明。

#!/usr/bin/env python
# encoding: utf-8
"""
binpack_simple.py
"""
from builtins import map
from builtins import range
from pyshipping.package import Package

from setuptools import setup, find_packages
from distutils.extension import Extension
import codecs
import time
import random




def packstrip(bin, p):
    """Creates a Strip which fits into bin.

    Returns the Packages to be used in the strip, the dimensions of the strip as a 3-tuple
    and a list of "left over" packages.
    """
    # This code is somewhat optimized and somewhat unreadable
    s = []                # strip
    r = []                # rest
    ss = sw = sl = 0      # stripsize
    bs = bin.heigth       # binsize
    sapp = s.append       # speedup
    rapp = r.append       # speedup
    ppop = p.pop          # speedup
    while p and (ss <= bs):
        n = ppop(0)
        nh, nw, nl = n.size
        if ss + nh <= bs:
            ss += nh
            sapp(n)
            if nw > sw:
                sw = nw
            if nl > sl:
                sl = nl
        else:
            rapp(n)
    return s, (ss, sw, sl), r + p


def packlayer(bin, packages):
    strips = []
    layersize = 0
    layerx = 0
    layery = 0
    binsize = bin.width
    while packages:
        strip, (sizex, stripsize, sizez), rest = packstrip(bin, packages)
        if layersize + stripsize <= binsize:
            packages = rest
            if not strip:
                # we were not able to pack anything
                break
            layersize += stripsize
            layerx = max([sizex, layerx])
            layery = max([sizez, layery])
            strips.extend(strip)
        else:
            # Next Layer please
            packages = strip + rest
            break
    return strips, (layerx, layersize, layery), packages


def packbin(bin, packages):
    packages.sort()
    layers = []
    contentheigth = 0
    contentx = 0
    contenty = 0
    binsize = bin.length
    while packages:
        layer, (sizex, sizey, layersize), rest = packlayer(bin, packages)
        if contentheigth + layersize <= binsize:
            packages = rest
            if not layer:
                # we were not able to pack anything
                break
            contentheigth += layersize
            contentx = max([contentx, sizex])
            contenty = max([contenty, sizey])
            layers.extend(layer)
        else:
            # Next Bin please
            packages = layer + rest
            break
    return layers, (contentx, contenty, contentheigth), packages


def packit(bin, originalpackages):
    packedbins = []
    packages = sorted(originalpackages)
    while packages:
        packagesinbin, (binx, biny, binz), rest = packbin(bin, packages)
        if not packagesinbin:
            # we were not able to pack anything
            break
        packedbins.append(packagesinbin)
        packages = rest
    # we now have a result, try to get a better result by rotating some bins

    return packedbins, rest


# In newer Python versions these van be imported:
# from itertools import permutations
def product(*args, **kwds):
    # product('ABCD', 'xy') --> Ax Ay Bx By Cx Cy Dx Dy
    # product(range(2), repeat=3) --> 000 001 010 011 100 101 110 111
    pools = list(map(tuple, args)) * kwds.get('repeat', 1)
    result = [[]]
    for pool in pools:
        result = [x + [y] for x in result for y in pool]
    for prod in result:
        yield tuple(prod)


def permutations(iterable, r=None):
    pool = tuple(iterable)
    n = len(pool)
    r = n if r is None else r
    for indices in product(list(range(n)), repeat=r):
        if len(set(indices)) == r:
            yield tuple(pool[i] for i in indices)


class Timeout(Exception):
    pass


def allpermutations_helper(permuted, todo, maxcounter, callback, bin, bestpack, counter):
    if not todo:
        return counter + callback(bin, permuted, bestpack)
    else:
        others = todo[1:]
        thispackage = todo[0]
        for dimensions in set(permutations((thispackage[0], thispackage[1], thispackage[2]))):
            thispackage = Package(dimensions, nosort=True)
            if thispackage in bin:
                counter = allpermutations_helper(permuted + [thispackage], others, maxcounter, callback,
                                                 bin, bestpack, counter)
            if counter > maxcounter:
                raise Timeout('more than %d iterations tries' % counter)
        return counter


def trypack(bin, packages, bestpack):
    bins, rest = packit(bin, packages)
    if len(bins) < bestpack['bincount']:
        bestpack['bincount'] = len(bins)
        bestpack['bins'] = bins
        bestpack['rest'] = rest
    if bestpack['bincount'] < 2:
        raise Timeout('optimal solution found')
    return len(packages)


def allpermutations(todo, bin, iterlimit=5000):
    random.seed(1)
    random.shuffle(todo)
    bestpack = dict(bincount=len(todo) + 1)
    try:
        # First try unpermuted
        trypack(bin, todo, bestpack)
        # now try permutations
        allpermutations_helper([], todo, iterlimit, trypack, bin, bestpack, 0)
    except Timeout:
        pass
    return bestpack['bins'], bestpack['rest']


def binpack(packages, bin=None, iterlimit=5000):
    """Packs a list of Package() objects into a number of equal-sized bins.

    Returns a list of bins listing the packages within the bins and a list of packages which can't be
    packed because they are to big."""
    if not bin:
        bin = Package("600x400x400")
    return allpermutations(packages, bin, iterlimit)


def test():
    fd = open('small.txt')
    vorher = 0
    nachher = 0
    start = time.time()
    for line in fd:
        packages = [Package(pack) for pack in line.strip().split()]
        if not packages:
            continue
        bins, rest = binpack(packages)
        if rest:
            print(("invalid data", rest, line))
        else:
            vorher += len(packages)
            nachher += len(bins)
    # print((time.time() - start))
    print((vorher, nachher, float(nachher) / vorher * 100))

#
if __name__ == '__main__':
    import cProfile
    cProfile.run('test()')


# packlayer(bin, packages)

Here是在线link到项目里面的文件

在Python3中支持__cmp__方法has been removed. You need to provide a __lt__ method for the class instead if you want to compare two instances. The code for the original Package.__cmp__ is here

新方法可能如下所示:

def __lt__(self, other):
    return self.volume < other.volume

但显然你应该彻底测试一下。

您需要将“音量”设置为您的排序键,意思是:
变化:

packages.sort()
packages = sorted(originalpackages)

收件人:

packages.sort(key=lambda x: x.volume)
packages = sorted(originalpackages, key=lambda x: x.volume)

因此,您无需手动更改任何包内码。