Simple Object assignment giving me errors

N

Nir

This is from the book 'dive into python'. I am trying to define jeez as being an instance of FileInfo.

class UserDict(object):
def __init__(self, dict = None):
self.data = {}
if dict is not None: self.update(dict)

class FileInfo(UserDict):
def __init__(self, filename=None):
UserDict.__init__(self)
self["name"] = filename


jeez = FileInfo("yo")




I get a TypeError: 'FileInfo' object doesn't support item assignment .

Am I missing something?
 
C

Chris Angelico

class FileInfo(UserDict):
def __init__(self, filename=None):
UserDict.__init__(self)
self["name"] = filename

I get a TypeError: 'FileInfo' object doesn't support item assignment .

Am I missing something?

You can't use square-brackets notation like that, unless you've
written your class specifically to handle it. More likely, what you
want is one of:

self.name = filename
self.dict["name"] = filename

Also, the same problem will occur with the UserDict, which tries to
update itself rather than its dict.

Actually, a simpler solution might be to have UserDict inherit from
dict. I'm not sure what you're trying to achieve here; more detail
would help. But if UserDict really is a dict, then you can call
self.update, and you can use square-brackets item assignment. I've no
idea what you'd gain over just using a dict though.

ChrisA
 
D

Dave Angel

Nir said:
This is from the book 'dive into python'. I am trying to define jeez as being an instance of FileInfo.

class UserDict(object):
def __init__(self, dict = None):
self.data = {}
if dict is not None: self.update(dict)

class FileInfo(UserDict):
def __init__(self, filename=None):
UserDict.__init__(self)
self["name"] = filename


jeez = FileInfo("yo")




I get a TypeError: 'FileInfo' object doesn't support item assignment .

Am I missing something?

Yes, you're missing the rest of the error message. Show the
whole thing, including the stack trace, and I'm sure it'll be
clear that the error happened long before jeez was involved.


I figure that the line in error is
self["name"] = filename

and that what you really need is
self.data ["name"] = filename

You also have a similar problem on the last line of the first class.
 
N

Nir

Those two classes are from this code here(pasted below). Quite frankly, I don't understand this code.

Also, UserDict is a built in module. I just typed it out so as to give reference or any clue as to why I cant instantiate jeez.

==========================================================================

"""Framework for getting filetype-specific metadata.

Instantiate appropriate class with filename. Returned object acts like a
dictionary, with key-value pairs for each piece of metadata.
import fileinfo
info = fileinfo.MP3FileInfo("/music/ap/mahadeva.mp3")
print "\\n".join(["%s=%s" % (k, v) for k, v in info.items()])

Or use listDirectory function to get info on all files in a directory.
for info in fileinfo.listDirectory("/music/ap/", [".mp3"]):
...

Framework can be extended by adding classes for particular file types, e.g.
HTMLFileInfo, MPGFileInfo, DOCFileInfo. Each class is completely responsible for
parsing its files appropriately; see MP3FileInfo for example.

This program is part of "Dive Into Python", a free Python book for
experienced programmers. Visit http://diveintopython.org/ for the
latest version.
"""

__author__ = "Mark Pilgrim ([email protected])"
__version__ = "$Revision: 1.3 $"
__date__ = "$Date: 2004/05/05 21:57:19 $"
__copyright__ = "Copyright (c) 2001 Mark Pilgrim"
__license__ = "Python"

import os
import sys
from UserDict import UserDict

def stripnulls(data):
"strip whitespace and nulls"
return data.replace("\00", " ").strip()

class FileInfo(UserDict):
"store file metadata"
def __init__(self, filename=None):
UserDict.__init__(self)
self["name"] = filename

class MP3FileInfo(FileInfo):
"store ID3v1.0 MP3 tags"
tagDataMap = {"title" : ( 3, 33, stripnulls),
"artist" : ( 33, 63, stripnulls),
"album" : ( 63, 93, stripnulls),
"year" : ( 93, 97, stripnulls),
"comment" : ( 97, 126, stripnulls),
"genre" : (127, 128, ord)}

def __parse(self, filename):
"parse ID3v1.0 tags from MP3 file"
self.clear()
try:
fsock = open(filename, "rb", 0)
try:
fsock.seek(-128, 2)
tagdata = fsock.read(128)
finally:
fsock.close()
if tagdata[:3] == 'TAG':
for tag, (start, end, parseFunc) in self.tagDataMap.items():
self[tag] = parseFunc(tagdata[start:end])
except IOError:
pass

def __setitem__(self, key, item):
if key == "name" and item:
self.__parse(item)
FileInfo.__setitem__(self, key, item)

def listDirectory(directory, fileExtList):
"get list of file info objects for files of particular extensions"
fileList = [os.path.normcase(f) for f in os.listdir(directory)]
fileList = [os.path.join(directory, f) for f in fileList \
if os.path.splitext(f)[1] in fileExtList]
def getFileInfoClass(filename, module=sys.modules[FileInfo.__module__]):
"get file info class from filename extension"
subclass = "%sFileInfo" % os.path.splitext(filename)[1].upper()[1:]
return hasattr(module, subclass) and getattr(module, subclass) or FileInfo
return [getFileInfoClass(f)(f) for f in fileList]

if __name__ == "__main__":
for info in listDirectory("/music/_singles/", [".mp3"]):
print "\n".join(["%s=%s" % (k, v) for k, v in info.items()])
print

========================================================================


If this makes sense to you, great. I am trying to break it down so that I can make sense of it. As you mentioned self["name"] = filename doesn't work unless I built a class to handle it. I guess my question then, is how is the class handling it in this code? If you can show me by stripping it downto the bare minimum or write an example that would be awesome.
 
C

Chris Angelico

Also, UserDict is a built in module. I just typed it out so as to give reference or any clue as to why I cant instantiate jeez.

Recommendation for next time: Don't type it out, copy and paste it.
Show the actual code you ran, and the actual error message.

As a debugging/exploration technique, btw, copying in the definition
of something from the standard library is often useful. You can then
cut it down to the barest minimum that does what you want, and post
that. But if you're using UserDict exactly as it is in the stdlib, you
can simply show your import statement and we'll know what you mean.

ChrisA
 
J

Jerry Hill

If this makes sense to you, great. I am trying to break it down so that Ican make sense of it. As you mentioned self["name"] = filename doesn't work unless I built a class to handle it. I guess my question then, is how is the class handling it in this code? If you can show me by stripping it down to the bare minimum or write an example that would be awesome.

This example works because the UserDict object being used in this code
was built to handle it. The UserDict class in the standard library
does a lot more than the little snippet you had in your original code.
Your original code would work if you did the same thing, like this:

from collections import UserDict

class FileInfo(UserDict):
def __init__(self, filename=None):
UserDict.__init__(self)
self["name"] = filename


jeez = FileInfo("yo")

(If you're using Python 2, then the first line should be "from
UserDict import UserDict" instead).

You can take a look at the source code for the userDict class here:
http://hg.python.org/cpython/file/3.3/Lib/collections/__init__.py#l862
.. In that class, the code responsible for handling the bracketed name
lookup (i.e., self["name"]), is in the __getitem__ and __setitem__
methods (and peripherally in __delitem__, __len__ and __contains__)
 
N

Nir

Thank you Jerry.

And thank you to the rest of you. You all have been tremendously helpful.

PS Chris, next time I will do just that.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top