<p>你不想为每首歌创建一个类;你想为每首歌创建一个类的<em>实例</em>。例如:</p>
<pre><code>class Song(object):
def __init__(self, name):
self.name = name
songNames = ['song1', 'song2', 'song3']
songs = []
for name in songNames:
songs.append(Song(name))
</code></pre>
<p>注意,我正在列表中存储<code>Song</code>对象。你需要把它们存储在某个地方,或者以后不能再访问它们,对吧?</p>
<p>如果您希望以后能够按名称访问它们,而不只是循环访问所有这些对象:</p>
<pre><code>songs = {}
for name in songNames:
songs[name] = Song(name)
</code></pre>
<p>你可以用一种理解力把它们转换成一行:</p>
<pre><code>songs = [Song(name) for name in songNames]
songs = {name: Song(name) for name in songNames}
</code></pre>
<hr/>
<p>从评论:</p>
<blockquote>
<p>I had intended by class to look something like the following, because every song was going to have all the same variables:</p>
</blockquote>
<pre><code>class songData:
title = ""
artist = ""
directory = ""
tempStr = ""
def description(self):
desc_str = "%s is by %s, located at %s" %(self.title, self.artist,self.directory)
return desc_str
</code></pre>
<p>这是错误的,原因与我已经解释过的相同:您创建的是类属性,而不是实例属性。这意味着每个实例都将共享一个标题等,这不是您想要的。而且,这意味着<code>self.title</code>是误导性的(尽管它会起作用)。</p>
<p>同时,如果这是Python2,您将再次创建一个经典类。另外,您可能需要一个<code>__str__</code>方法,而不是一个特殊的<code>description</code>方法,因为这样您就可以<code>print(song)</code>而不必<code>print(song.description())</code>。最后,对变量和类使用相同的命名约定有点混乱。</p>
<p>你可能想要的是:</p>
<pre><code>class SongData:
def __init__(self, title="", artist="", directory=""):
self.title, self.artist, self.directory = title, artist, directory
def __str__(self):
desc_str = "%s is by %s, located at %s" % (self.title, self.artist,self.directory)
return desc_str
</code></pre>
<p>现在,您可以使用与上面的<code>Song</code>类基本相同的方法:</p>
<pre><code>songNames = ['song1', 'song2', 'song3']
songs = {name: SongData(title=name) for name in songNames}
</code></pre>
<p>现在你可以这样做:</p>
<pre><code>name = input('What song do you want info on?') # raw_input, if Python 2
print(songs[name])
</code></pre>
<p>(当然,这不是很有用,除非您也有设置艺术家和目录的代码,因为它只会打印<code>Song Windowlicker is by , located at</code>。但我不知道你打算从哪里弄到这些。)</p>
<hr/>
<p>你的新代码有两个问题。首先:</p>
<pre><code>def __str__(self):
desc_str = "Title: %s \nArtist: %s \nDirectory: %s \n" %(self.title,
self.artist, self.directory)
print desc_str
</code></pre>
<p>你需要<code>return desc_str</code>在这里,而不是<code>print</code>它。</p>
<hr/>
<p>第二:</p>
<pre><code>songNames = ['song1', 'song2', 'song3']
artistNames = ['artist1', 'artist2', 'artist3']
dirNames = ['dir1', 'dir2', 'dir3']
songs = {name: SongData(title=name) for name in songNames}
artists = {band: SongData(artist=band) for band in artistNames}
directorys = {direc: SongData(directory=direc) for direc in dirNames}
</code></pre>
<p>在这里,您将创建三个独立的<code>SongData</code>对象集合,每个对象只填充一个属性。</p>
<p>这里的关键是<a href="http://docs.python.org/2/library/functions.html#zip" rel="nofollow">^{<cd12>}</a>。它是Python中最有用的函数之一,一旦你了解了它的功能,但是除非你知道它,否则你永远不会去寻找它。如果我展示它的功能,就更容易描述:</p>
<pre><code>>>> zip(songNames, artistNames, dirNames)
[('song1', 'artist1', 'dir1'),
('song2', 'artist2', 'dir2'),
('song3', 'artist3', 'dir3')]
</code></pre>
<p>所以,这给了你一个元组列表,每个元组有一个歌曲名,一个艺术家和一个目录。第一个元组是每个元组的第一个元组,第二个元组是每个元组的第二个元组,等等</p>
<p>现在,您可以很容易地从每个元组构建一个<code>SongData</code>:</p>
<pre><code>songs = {}
for title, artist, directory in zip(songNames, artistNames, dirNames):
songs[title] = SongData(title, artist, directory)
</code></pre>
<p>作为一种听写理解,它有点冗长:</p>
<pre><code>songs = {title: SongData(title, artist, directory)
for title, artist, directory in zip(songNames, artistNames, dirNames)}
</code></pre>
<p>但是你可以用另一个技巧来简化它:<a href="http://docs.python.org/2/tutorial/controlflow.html#unpacking-argument-lists" rel="nofollow">unpacking arguments</a>:</p>
<pre><code>songs = {t[0]: SongData(*t) for songtuple in zip(songNames, artistNames, dirNames)}
</code></pre>
<p>当然,你不需要<code>zip</code>就可以做到这一点,但这看起来很混乱:</p>
<pre><code>songs = {SongData(songNames[i], artistNames[i], dirNames[i])
for i in range(len(songNames))}
</code></pre>
<p>…如果有一个列表不匹配的小错误,那么很难通过这种方式理解和调试。一般来说,无论何时用Python编写<code>for i in range(len(foo))</code>,可能有一种简单的方法。</p>
<hr/>
<p>无论您如何构建它,您都可以像预期的那样使用它:</p>
<pre><code>>>> print songs['song1']
Title: song1
Artist: artist1
Directory: directory1
</code></pre>
<hr/>
<p>当我们在它的时候,你可能不希望在每行输出的末尾都有一个空格。它对人类来说是不可见的,但它可能会混淆您稍后编写的解析输出的代码,而且它会浪费空间,而且没有真正的好处。把每个<code>\n</code>放在<code>%s</code>后面。</p>