- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
如果这是一个菜鸟问题,我深表歉意,但我似乎无法弄清楚这个问题。
我已经定义了一个定义音乐轨道的对象(注意:最初只有 ATTRIBUTE 与 self.ATTRIBUTE。我编辑了这些值以帮助消除混淆。它们对问题没有影响)
class Track(object):
def __init__(self, title, artist, album, source, dest):
"""
Model of the Track Object
Contains the followign attributes:
'Title', 'Artist', 'Album', 'Source', 'Dest'
"""
self.atrTitle = title
self.atrArtist = artist
self.atrAlbum = album
self.atrSource = source
self.atrDest = dest
我使用 ObjectListView 在特定目录中创建轨道列表
....other code....
self.aTrack = [Track(sTitle,sArtist,sAlbum,sSource, sDestDir)]
self.TrackOlv.AddObjects(self.aTrack)
....other code....
现在我想迭代列表并打印出每个项目的单个值
list = self.TrackOlv.GetObjects()
for item in list:
print item.atrTitle
失败并出现错误
AttributeError: type object 'Track' has no attribute 'atrTitle'
真正让我感到困惑的是,如果我在对象 ListView 显示中突出显示单个项目并使用以下代码,它将正确地打印出突出显示项目的单个值
list = self.TrackOlv.GetSelectedObject()
print list.atrTitle
编辑:每个请求的完整源代码。要查看错误,请浏览到带有 .mp3 文件的源目录,然后单击打印按钮。
#Boa:Frame:Frame1
import wx
import os
import glob
import shutil
import datetime
from mutagen.mp3 import MP3
from mutagen.easyid3 import EasyID3
import mutagen.id3
import unicodedata
from ObjectListView import ObjectListView, ColumnDefn
########################################################################
class Track(object):
def __init__(self, title, artist, album, source, dest):
"""
Model of the Track Object
Contains the followign attributes:
'Title', 'Artist', 'Album', 'Source', 'Dest'
"""
self.atrTitle = title
self.atrArtist = artist
self.atrAlbum = album
self.atrSource = source
self.atrDest = dest
class Action(object):
def __init__(self, timestamp, action, result):
self.timestamp = timestamp
self.action = action
self.result = result
########################################################################
# Non GUI
########################################################################
def selectFolder(sMessage):
print "Select Folder"
dlg = wx.DirDialog(None, message = sMessage)
if dlg.ShowModal() == wx.ID_OK:
# User has selected something, get the path, set the window's title to the path
filename = dlg.GetPath()
else:
filename = "None Selected"
dlg.Destroy()
return filename
def getList(SourceDir):
print "getList"
listOfFiles = None
print "-list set to none"
listOfFiles = glob.glob(SourceDir + '/*.mp3')
return listOfFiles
def getListRecursive(SourceDir):
print "getListRecursive"
listOfFiles = None
listOfFiles = []
print "-list set to none"
for root, dirs, files in os.walk(SourceDir):
for file in files:
if file.endswith(".mp3"):
listOfFiles.append(os.path.join(root,file))
#print listOfFiles
return listOfFiles
def strip_accents(s):
print "strip_accents"
return ''.join((c for c in unicodedata.normalize('NFD', s) if unicodedata.category(c) != 'Mn'))
def replace_all(text):
print "replace_all " + text
dictionary = {'\\':"", '?':"", '/':"", '...':"", ':':"", '&':"and"}
print text
print text.decode('utf-8')
text = strip_accents(text.decode('utf-8'))
for i, j in dictionary.iteritems():
text = text.replace(i,j)
return text
def getTitle(fileName):
print "getTitle"
audio = MP3(fileName)
try:
sTitle = str(audio["TIT2"])
except KeyError:
sTitle = os.path.basename(fileName)
frame.lvActions.Append([datetime.datetime.now(),fileName,"Title tag does not exist, set to filename"])
# TODO: Offer to set title to filename
## If fileName != filename then
## prompt user for action
## Offer Y/n/a
sTitle = replace_all(sTitle)
return sTitle
def getArtist(fileName):
print "get artist"
audio = MP3(fileName)
try:
sArtist = str(audio["TPE1"])
except KeyError:
sArtist = "unkown"
frame.lvActions.Append([datetime.datetime.now(),fileName,"Artist tag does not exist, set to unkown"])
#Replace all special chars that cause dir path errors
sArtist = replace_all(sArtist)
#if name = 'The Beatles' change to 'Beatles, The'
if sArtist.lower().find('the') == 0:
sArtist = sArtist.replace('the ',"")
sArtist = sArtist.replace('The ',"")
sArtist = sArtist + ", The"
return sArtist
def getAblum(fileName):
print "get album"
audio = MP3(fileName)
try:
sAlbum = str(audio["TALB"])
except KeyError:
sAlbum = "unkown"
frame.lvActions.Append([datetime.datetime.now(),fileName,"Album tag does not exist, set to unkown"])
#Replace all special chars that cause dir path error
sAlbum = replace_all(sAlbum)
return sAlbum
########################################################################
# GUI
########################################################################
class MainPanel(wx.Panel):
#----------------------------------------------------------------------
def __init__(self, parent):
wx.Panel.__init__(self, parent=parent, id=wx.ID_ANY)
self.TrackOlv = ObjectListView(self, wx.ID_ANY,
style=wx.LC_REPORT|wx.SUNKEN_BORDER)
self.setTracks()
# Allow the cell values to be edited when double-clicked
self.TrackOlv.cellEditMode = ObjectListView.CELLEDIT_SINGLECLICK
self.ActionsOlv = ObjectListView(self, wx.ID_ANY,
style=wx.LC_REPORT|wx.SUNKEN_BORDER)
self.setActions()
# create browse to source button
sourceBtn = wx.Button(self, wx.ID_ANY, "Browse Source")
sourceBtn.Bind(wx.EVT_BUTTON, self.onBrowseSource)
# create source txt box
self.txSource = wx.TextCtrl(self, wx.ID_ANY, name=u'txSource', value=u'')
# create browse dest button
destBtn = wx.Button(self, wx.ID_ANY, "Browse Destination")
destBtn.Bind(wx.EVT_BUTTON, self.onBrowseDest)
# create dest txt box
self.txDest = wx.TextCtrl(self, wx.ID_ANY, name=u'txDest', value=u'')
# create Move Files button
moveBtn = wx.Button(self, wx.ID_ANY, "Move Files")
moveBtn.Bind(wx.EVT_BUTTON, self.onMoveFiles)
# print list button - debug only
printBtn = wx.Button(self, wx.ID_ANY, "Print List")
printBtn.Bind(wx.EVT_BUTTON, self.onPrintBtn)
# create check box to include all sub files
self.cbSubfolders = wx.CheckBox(self, wx.ID_ANY,
label=u'Include Subfolders', name=u'cbSubfolders', style=0)
self.cbSubfolders.SetValue(True)
self.cbSubfolders.Bind(wx.EVT_CHECKBOX, self.OnCbSubfoldersCheckbox)
# create check box to repace file names
self.cbReplaceFilename = wx.CheckBox(self, wx.ID_ANY,
label=u'Replace Filename with Title Tag',
name=u'cbReplaceFilename', style=0)
self.cbReplaceFilename.SetValue(False)
self.cbReplaceFilename.Bind(wx.EVT_CHECKBOX, self.OnCbReplaceFilenameCheckbox)
# Create some sizers
mainSizer = wx.BoxSizer(wx.VERTICAL)
feedbackSizer = wx.BoxSizer(wx.VERTICAL)
sourceSizer = wx.BoxSizer(wx.HORIZONTAL)
btnSizer = wx.BoxSizer(wx.HORIZONTAL)
feedbackSizer.Add(self.TrackOlv, 1, wx.ALL|wx.EXPAND, 2)
feedbackSizer.Add(self.ActionsOlv, 1, wx.ALL|wx.EXPAND, 2)
sourceSizer.Add(sourceBtn, 0, wx.ALL, 2)
sourceSizer.Add(self.txSource, 1, wx.ALL|wx.EXPAND, 2)
sourceSizer.Add(destBtn, 0, wx.ALL, 2)
sourceSizer.Add(self.txDest, 1, wx.ALL|wx.EXPAND, 2)
btnSizer.Add(printBtn)
btnSizer.Add(moveBtn, 0, wx.ALL, 2)
btnSizer.Add(self.cbSubfolders, 0, wx.ALL, 2)
btnSizer.Add(self.cbReplaceFilename, 0, wx.ALL, 2)
mainSizer.Add(feedbackSizer, 1 , wx.ALL|wx.EXPAND, 2)
mainSizer.Add(sourceSizer, 0, wx.ALL|wx.EXPAND, 2)
#mainSizer.Add(destSizer, 0, wx.ALL|wx.EXPAND, 2)
#mainSizer.Add(destSizer, 0, wx.All|wx.Expand, 2)
mainSizer.Add(btnSizer, 0, wx.ALL, 2)
self.SetSizer(mainSizer)
mainSizer.Fit(self)
#----------------------------------------------------------------------
# Set the GUI column headers and width
#----------------------------------------------------------------------
def setTracks(self, data=None):
self.TrackOlv.SetColumns([
ColumnDefn("Title", "left", 100, "title"),
ColumnDefn("Artist", "left", 100, "artist"),
ColumnDefn("Album", "left", 100, "album"),
ColumnDefn("Source", "left", 300, "source"),
ColumnDefn("Destination", "left", 300, "dest"),
])
def setActions(self, data=None):
self.ActionsOlv.SetColumns([
ColumnDefn("Time", "left", 100, "timestamp"),
ColumnDefn("Action", "left", 450, "action"),
ColumnDefn("Result", "left", 450, "result")
])
#----------------------------------------------------------------------
# GUI EVENTS
#-----------------------------------------------------------------------
EventList = [Action]
#Select Source of files
def onBrowseSource(self, event):
print "OnBrowseSource"
source = selectFolder("Select the Source Directory")
print source
self.txSource.SetValue(source)
self.anEvent = [Action(datetime.datetime.now(),source,"Set as Source dir")]
self.ActionsOlv.AddObjects(self.anEvent)
self.populateList()
#Select Source of files
def onBrowseDest(self, event):
print "OnBrowseDest"
dest = selectFolder("Select the Destination Directory")
print dest
self.txDest.SetValue(dest)
self.anEvent = [Action(datetime.datetime.now(),dest,"Set as Destination dir")]
self.ActionsOlv.AddObjects(self.anEvent)
self.populateList()
def OnCbSubfoldersCheckbox(self, event):
print "cbSubfolder"
self.populateList()
def OnCbReplaceFilenameCheckbox(self, event):
print "cbReplaceFilename"
self.populateList()
def onMoveFiles(self, event):
print "onMoveFiles"
self.moveFiles()
def onPrintBtn(self, event):
print "onPrintBtn"
#Why does this work
#rowObj = self.dataOlv.GetSelectedObject()
#print rowObj.author
#print rowObj.title
#debug - how many item in the list... why does it only print 1?
test = self.TrackOlv.GetItemCount()
print test
print "aphex"
print self.TrackOlv.GetObjects()
for item in xrange(self.TrackOlv.GetItemCount()):
stitle = self.TrackOlv.GetObjectAt(item)
print stitle.atrTitle
#-------------
#Computations
#-------------
def defineDestFilename(self, sFullDestPath):
print "define dest"
iCopyX = 0
bExists = False
sOrigName = sFullDestPath
#If the file does not exist return original path/filename
if os.path.isfile(sFullDestPath) == False:
print "-" + sFullDestPath + " is valid"
return sFullDestPath
#Add .copyX.mp3 to the end of the file and retest until a new filename is found
while bExists == False:
sFullDestPath = sOrigName
iCopyX += 1
sFullDestPath = sFullDestPath + ".copy" + str(iCopyX) + ".mp3"
if os.path.isfile(sFullDestPath) == False:
print "-" + sFullDestPath + " is valid"
self.lvActions.Append([datetime.datetime.now(),"Desitnation filename changed since file exists",sFullDestPath])
bExists = True
#return path/filename.copyX.mp3
return sFullDestPath
def populateList(self):
print "populateList"
sSource = self.txSource.Value
sDest = self.txDest.Value
#Initalize list to reset all values on any option change
self.initialList = [Track]
self.TrackOlv.SetObjects(self.initialList)
#Create list of files
if self.cbSubfolders.Value == True:
listOfFiles = getListRecursive(sSource)
else:
listOfFiles = getList(sSource)
print listOfFiles
#prompt if no files detected
if listOfFiles == []:
self.anEvent = [Action(datetime.datetime.now(),"Parse Source for .MP3 files","No .MP3 files in source directory")]
self.ActionsOlv.AddObjects(self.anEvent)
#Populate list after both Source and Dest are chosen
if len(sDest) > 1 and len(sDest) > 1:
print "-iterate listOfFiles"
for file in listOfFiles:
(sSource,sFilename) = os.path.split(file)
print sSource
print sFilename
#sFilename = os.path.basename(file)
sTitle = getTitle(file)
try:
sArtist = getArtist(file)
except UnicodeDecodeError:
print "unicode"
sArtist = "unkown"
sAlbum = getAblum(file)
# Make path = sDest + Artist + Album
sDestDir = os.path.join (sDest, sArtist)
sDestDir = os.path.join (sDestDir, sAlbum)
#If file exists change destination to *.copyX.mp3
if self.cbReplaceFilename.Value == True:
sDestDir = self.defineDestFilename(os.path.join(sDestDir,sTitle))
else:
sDestDir = self.defineDestFilename(os.path.join(sDestDir,sFilename))
# Populate listview with drive contents
#sSource = self.txSource.Value
sDest = self.txDest.Value
# TODO: Make source = exact source of track, not parent source
# TODO: Seperate dest and filename
self.aTrack = Track(sTitle,sArtist,sAlbum,sSource, sDestDir)
self.TrackOlv.AddObjects(self.aTrack)
self.Update()
#populate list to later use in move command
#self.validatedMove.append([file,sDestDir])
print "-item added to SourceDest list"
else:
print "-list not iterated"
def moveFiles (self):
print "move files"
#for track in self.TrackOlv:
# print "-iterate SourceDest"
# #create dir
# (sDest,filename) = os.path.split(self.TrackOlv)
# print "-check dest"
#
# if not os.path.exists(sDest):
# print "-Created dest"
# os.makedirs(sDest)
# self.lvActions.Append([datetime.datetime.now(),sDest,"Created"])
# self.Update()
# self.lvActions.EnsureVisible(self.lvActions.GetItemCount() -1)
#
# #Move File
# print "-move file"
# shutil.move(SourceDest[0],SourceDest[1])
# self.lvActions.Append([datetime.datetime.now(),filename,"Moved"])
# self.Update()
# self.lvActions.EnsureVisible(self.lvActions.GetItemCount() -1)
#
#self.lvActions.Append([datetime.datetime.now(),"Move Complete","Success"])
#self.Update()
#self.lvActions.EnsureVisible(self.lvActions.GetItemCount() -1)
########################################################################
class MainFrame(wx.Frame):
#----------------------------------------------------------------------
def __init__(self):
wx.Frame.__init__(self, parent=None, id=wx.ID_ANY,
title="MP3 Manager", size=(1024,768)) #W by H
panel = MainPanel(self)
########################################################################
class GenApp(wx.App):
#----------------------------------------------------------------------
def __init__(self, redirect=False, filename=None):
wx.App.__init__(self, redirect, filename)
#----------------------------------------------------------------------
def OnInit(self):
# create frame here
frame = MainFrame()
frame.Show()
return True
#----------------------------------------------------------------------
def main():
"""
Run the demo
"""
app = GenApp()
app.MainLoop()
if __name__ == "__main__":
main()
最佳答案
你没有包含错误:
....other code....
self.aTrack = [Track(sTitle,sArtist,sAlbum,sSource, sDestDir)]
self.TrackOlv.AddObjects(self.aTrack)
....other code....
它在第一个“....其他代码....”的某处,可能在您第一次创建 self.TrackOlv 的那一行。
查看您的错误信息:
AttributeError: type object 'Track' has no attribute 'atrTitle'
这是说实际的类(“类型对象‘Track’”)缺少该属性。也就是说,您已将实际类 Track 添加到列表中,而不是该类的实例。它可能是列表中的第一项,或者您的循环会在抛出错误之前打印一些标题。
请注意以下不同的错误消息:
>>> class Foo(object): pass
...
>>> Foo.cat
Traceback (most recent call last):
File "<input>", line 1, in <module>
AttributeError: type object 'Foo' has no attribute 'cat'
>>> Foo().cat
Traceback (most recent call last):
File "<input>", line 1, in <module>
AttributeError: 'Foo' object has no attribute 'cat'
关于python 对象 AttributeError : type object 'Track' has no attribute 'title' ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5079500/
我正在努力掌握 perl。我正在尝试编写一些脚本作为调度模拟器。 FCFS、SSTF 和 Scan and Look 我有一个包含 block 请求列表的数组,另一个用作缓冲区。首先,我将复制第一个请
假设我正在ng-repeat处理images,它是一个包含src 和 的对象数组>标题属性。 var images = [ {src: 'a.jpg', caption: 'a'}, {src
“git branch --track”和“git checkout -b --track”之间有什么区别,如果有的话? 最佳答案 内部 git-branch 被调用,然后新分支被 check out
我在自定义 Android Switch 小部件的外观时遇到问题。我有自定义的 xml 可绘制对象,我想将其用于拇指(通常显示开或关的小按钮部分)和轨道(拇指滑过的背景)。当我使用 android:t
文档有点太简单了,我无法完全理解 A controller thus effectively has three modes of operation, determined by whether i
已在 Google Analytics(分析)帮助论坛中发布此内容,但无人能提供帮助。希望我在这里有更多的运气......: 我对我的网页使用 Google Anlaytics 异步跟踪。像个魔法一样
我有一个简单的ng-repeat,其中track by表达式不起作用。这是Fiddle . {{n}} 生成的标记“track”是表达式 [[1,2,3,4,5,5,5,5] track
我想使用 Spotify iOS SDK 从选定的播放列表中获取轨道。但它总是不返回我的数组中的任何项目。我正在使用以下代码来获取轨道: [SPTPlaylistSnapshot playlistWi
我正在尝试将一维数组分配给我的默认构造函数,但我不断收到此错误消息。有没有办法为同一个类创建两个默认构造函数,一个不带参数,一个带参数? 标题 #include #include using na
问题中的答案Android play console: internal testing version, close testing ? how does it works?说: End users
也许有人可以告诉我如何在 Switch() 中设置 Track Width、Track StrokeWidth、Thumb Diameter 的大小 Switch(
我有一个适用于 Android 和 iOS 的移动应用,两者都是使用 Xamarin 构建的。 Android - 该应用会上传到 Beta 轨道 上的 Play 商店,测试完成后,就会升级到生产轨道
我在我的 http 请求中发送一个 Json 格式的用户实体,如下所示: POST http://localhost:52054/api/Authentication/DeleteAccessToke
我正在研究 Java 类介绍的最终项目。该项目的一部分涉及从 MusixMatch using their API 获取歌词片段。我可以使用 track.lyrics.get 从 API 获取歌词,但
我将 ASP.NET Core 与 EFCore 2.0.3 和 Automapper 6.2.2 一起使用 这是我的模型: public class StudentClass {
所以我同时使用 react-native-video 和 react-native-track-player,通常两者都工作正常,但是要使用视频播放器的一些额外功能,比如缓冲,我必须使用 Exo pl
有时我听到人们讨论跟踪编程错误的好处,如果不是为了提高对常见错误的认识的话。我已经开始保留我在代码中发现的错误列表,以及可能导致这些错误的原因。我的主要问题是: 我应该保留哪些与我的错误相关的信息 跟
可以对卡尔曼滤波器更新的估计值应用上限和下限约束吗? 我有一种在实际生活中只能有非负值的状态。当我应用卡尔曼滤波器时,此状态会更新为具有负值。如何在卡尔曼滤波器中应用此限制约束? 请回复 谢谢 最佳答
我正在构建一个使用Sendgrid Marketing Email API的应用程序,目的是发送新闻通讯。它具有许多文章链接,还包括横幅广告和其他服务链接。我们显然希望继续跟踪文章链接,但要排除其他链
我所在的团队管理着许多软件项目 - 我们所做的大部分工作都是端到端的,从需求跟踪到项目管理再到采购和设置 - 财务跟踪是我们的一大难题我们的财务有一个完整的过程。目前我们使用电子表格并将所有发票和采购
我是一名优秀的程序员,十分优秀!