【问题标题】:Python - Return a value from a tuplePython - 从元组返回一个值
【发布时间】:2014-04-27 16:49:17
【问题描述】:

我正在使用pyacoustid,但我不明白为什么这段代码有效(艺术家实际上是艺术家等等..):

first = True
        for score, rid, title, artist in self.fpresults:
            if first:
                first = False
            else:
                print
            print '%s - %s' % (artist, title)
            print 'http://musicbrainz.org/recording/%s' % rid
            print 'Score: %i%%' % (int(score * 100))

虽然这个块没有(当我打印时它似乎是空的):

def getFingerprintArtist(self):
        """
        Returns tuples with possible artists fetched from the MusicBrainz DB
        """
        return  [artist for score, rid, title, artist in self.fpresults]

这是整个班级(欢迎提出建议!):

class SongFP:
    """
    Song with FINGERPRINTS
    """
    fpresults = None

    def __init__(self, path = None):
        """
        :param path: the path of the song
        """
        self.path = path
        try:
            self.fpresults = acoustid.match(api_key, path)
        except acoustid.NoBackendError:
            logger(paths['log'], "ERROR: chromaprint library/tool not found")
        except acoustid.FingerprintGenerationError:
            logger(paths['log'], "ERROR: fingerprint could not be calculated")
        except acoustid.WebServiceError, exc:
            logger(paths['log'], ("ERROR: web service request failed: %s" % exc.message))

    def setPath(self, path):
        self.path = path

    def printResults(self):
        first = True
        for score, rid, title, artist in self.fpresults:
            if first:
                first = False
            else:
                print
            print '%s - %s' % (artist, title)
            print 'http://musicbrainz.org/recording/%s' % rid
            print 'Score: %i%%' % (int(score * 100))

    def setFPResults(self):
        self.fpresults = acoustid.match(api_key, self.path)

    def getFingerprintArtist(self):
        """
        Returns tuples with possible artists fetched from the MusicBrainz DB
        """
        return [artist for score, rid, title, artist in self.fpresults]

    def getFingerprintTitle(self):
        """
        Returns tuples with possible titles fetched from the MusicBrainz DB
        """
        return [title for score, rid, title, artist in self.fpresults]

    def getFingerPrintID(self):
        """
        Returns tuples with IDs fetched from the MusicBrainz DB
        """
        return [rid for score, rid, title, artist in self.fpresults]

    def getFingerPrintScore(self):
        """
        Returns tuples with scores fetched from the MusicBrainz DB
        """
        return [score for score, rid, title, artist in self.fpresults]

注意: acoustid.match(api_key, path) 返回元组!

编辑:

这个小例子

songfp = SongFP(sys.argv[1])
songfp.printResults()

SongFP 在哪里

class SongFP:
    """
    Song with FINGERPRINTS
    """
    fpresults = None

def __init__(self, path = None):
    """
    :param path: the path of the song
    """
    self.path = path
    try:
        self.fpresults = acoustid.match(api_key, path)
    except acoustid.NoBackendError:
        logger(paths['log'], "ERROR: chromaprint library/tool not found")
    except acoustid.FingerprintGenerationError:
        logger(paths['log'], "ERROR: fingerprint could not be calculated")
    except acoustid.WebServiceError, exc:
        logger(paths['log'], ("ERROR: web service request failed: %s" % exc.message))

def getFingerprintArtist(self):
        """
        Returns tuples with possible artists fetched from the MusicBrainz DB
        """
        return [artist for _, _, _, artist in self.fpresults]

def getFingerprintTitle(self):
    """
    Returns tuples with possible titles fetched from the MusicBrainz DB
    """
    return [title for _, _, title, _ in self.fpresults]

def getFingerprintID(self):
    """
    Returns tuples with IDs fetched from the MusicBrainz DB
    """
    return [rid for _, rid, _, _ in self.fpresults]

def getFingerprintScore(self):
    """
    Returns tuples with scores fetched from the MusicBrainz DB
    """
    return [score for score, _, _, _ in self.fpresults]

def printResults(self):
        print("Titles: %s" % self.getFingerprintTitle())
        print("Artists: %s" % self.getFingerprintArtist())
        print("IDs: %s" % self.getFingerprintID())
        print("Scores: %s" % self.getFingerprintScore())

当被称为./app song.mp3 时,只输出某个字段(如果一个字段为空,则其他字段也应为空,反之亦然,因为它会获取在线 MP3 元数据)

Titles: [u'Our Day Will Come', u'Our Day Will Come', u'Our Day Will Come', u'Our Day Will Come', u'Our Day Will Come']
Artists: []
IDs: []
Scores: []

日志中没有例外!

【问题讨论】:

  • 请发布异常回溯。
  • 我已经检查了日志,没有出现异常。
  • 你说它不起作用。我们需要更多信息。如果代码没有产生异常,那么发生了什么?
  • 这正是我写问题的原因!
  • @Krishath 让我们换一种说法 - 你希望它做什么而它没有做什么?

标签: python oop methods instance generator


【解决方案1】:

这很难诊断,但通常更常见的是这样分配你不使用的变量:

def getFingerprintArtist(self):
    """
    Returns (list of)* possible artists fetched from the MusicBrainz DB
    """
    return  [artist for _, _, _, artist in self.fpresults]

您能否将其重写为一个可重现的最小示例,以便我们提供进一步的指导?

*这不是返回一个元组,它只是返回一个(语义上)艺术家姓名的列表!


编辑分析

我认为这里发生的事情是您正在耗尽发电机。

self.fpresults

在对象的实例化中填充一次,而不是在您的 __init__ 中执行以下操作:

try:
    self.fpresults = list(acoustid.match(api_key, path))

它将生成器生成的信息作为属性保存在内存中,直到不再引用listSongFP 对象,然后进行垃圾回收。

【讨论】:

  • 太棒了!这就是问题所在!您能否将我链接到一些参考资料以更好地了解发生了什么?
  • 这里是关于生成器的 Python 教程:docs.python.org/2/tutorial/classes.html#generators 但基本情况是,一旦你迭代了一个生成器,它就已经用尽了,除非它提供了一种返回更早点的方法(文件/io读者可以这样做)但在你的情况下,这可能不太可能。它们的优点是它们不会一次将所有信息都具体化。缺点是它们通常必须重新创建才能再次使用。
【解决方案2】:

如果它们只是元组,你可以这样做:

def get_value_at_index(tuple_list, index):
    """Returns a list of the values at a given index."""
    return [tup[index] for tup in tuple_list]

【讨论】:

  • 请检查整个代码,因为我认为我的功能做得很好,但还有其他问题。
【解决方案3】:

[artist for score, rid, title, artist in self.fpresults]

您只是商店艺术家。你需要这样的东西:

[(artist, score, rid, title) for artist, score, rid, title in self.fpresults]

【讨论】:

  • 这就是函数的作用。检查函数名称。
  • 哦,我明白了,在这种情况下,您可以更改该函数的文档注释吗?请问?
猜你喜欢
  • 2015-07-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多