[Pythonmac-SIG] Where to put data

Bob Ippolito bob at redivi.com
Wed Dec 22 01:45:23 CET 2004


On Dec 21, 2004, at 6:57 PM, Charles Hartman wrote:

> On Dec 21, 2004, at 3:32 PM, Bob Ippolito wrote:
>
>> On Dec 21, 2004, at 10:23 AM, Charles Hartman wrote:
>>
>>> (I also posted this to wxusers because it's sort of cross-platform  
>>> -- sorry if you're seeing it again.)
>>>
>>> With an earlier app I wanted an external data file and everybody  
>>> told me to make it internal to the program (the app's Resources, I  
>>> guess) instead. I couldn't, then. Now with a new app I want to do  
>>> just that, but I'm not sure *how* to do it!
>>>
>>> It's a file of data -- a Python dictionary object, after it's loaded  
>>> into memory -- which will grow and change as the app is used; when  
>>> the app terminates the data ought to be saved  with it for next  
>>> time. In this case I don't want users fiddling with it apart from  
>>> the app.
>>>
>>> What is the right way to do this? (What's the easy way?) Is there a  
>>> simple method that will work for both Mac and Windows (and Linux)?
>>
>> The right way to do it is NOT to have this file inside your  
>> application.  You should *never* assume that you can write to your  
>> own application bundle.  You *should* have a way to create this file  
>> from scratch (which may be a template file inside Resources, which is  
>> never written to).
>>
>> As others have said there are different places you should put this  
>> file dependent on operating system..
>>
>> On Mac OS X it should probably go in one of the "Application Support"  
>> directories.  It's common convention to only place plist formatted  
>> files in the Preferences directory, so unless you're serializing this  
>> dictionary as a plist, I suggest going with Application Support  
>> instead of Preferences.
>>
>> On other *nix, it would typically go into a ~/.yourapplication  
>> directory.
>>
>> And for Windows, somewhere in their home directory (at least on  
>> NT-based Windows).  Optionally, you could put it in the registry  
>> instead, which may be a good idea, depending on how big it is  
>> expected to get.
>>
>> As far as writing to your own application goes, here's a short list  
>> of why that's bad:
>> - Will not work from CD-ROM, compressed disk image, etc.
>> - Probably will not work multi-user
>> - Probably a bad idea if the application is on a network drive
>> - User may not have permissions to write to the application
>> - If you break it, you really broke it.
>> - It can look virus-like and be picked up as such (particularly on  
>> Win32 if you're writing to the .exe file).
>>
>> You should be able to trust the user not to fiddle with it apart from  
>> the app.  Especially if it's a pickle file.  It will be pretty  
>> buried, anyway.
>>
> OK, all this makes sense. But I'm startled to see how incredibly  
> gnarly it is to have any kind of data -- if you want to preserve  
> changes in the data, say by having a dictionary grow from one program  
> run to the next -- at least on more than one platform. Is this so  
> uncommon a pattern for applications? Oh well.

You make it sound much harder than it is.  Yes, for the three major  
platforms, there are three different canonical ways.

win32: registry is easy, especially using something like this:  
http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/174627
OS X: NSUserDefaults is painless via PyObjC:  
http://developer.apple.com/documentation/Cocoa/Reference/Foundation/ 
ObjC_classic/Classes/NSUserDefaults.html
posix: otherwise, roll your own: appdir =  
os.path.expanduser("~/.myapplication"); if not os.path.exists(appdir):  
os.makedirs(appdir); ....

You could more or less use the dot directory method for all three  
platforms if you were a cross-platform purist, it should work, at least  
for NT-based windows.  There's probably an abstraction for this  
somewhere.

-bob



More information about the Pythonmac-SIG mailing list