This does the thing, I do not know how good programming style it is to change own code, though:
## My program
import sys
def between(left,right,s):
before,_,a = s.partition(left)
a,_,after = a.partition(right)
return before,a,after
my_value=2160278.18574
print 'Old value',my_value
my_value=1.2*my_value
print 'New value', my_value
my_code=open(sys.argv[0]).read()
beginning,value,rest=between('my_value=','\n',my_code)
open(sys.argv[0],'w').write(beginning + 'my_value=' + str(my_value) + '\n' + rest)
input('Ready')
pyTony
pyMod
5,359 posts since Apr 2010
Reputation Points: 782
Solved Threads: 852
pyTony
pyMod
5,359 posts since Apr 2010
Reputation Points: 782
Solved Threads: 852
Response to tonyjv: it is a horrible idea to self-modify your code. You can make wonderful messes, though it is kind of fun if you don't have to maintain it. I *think* that the fact the script is byte compiled means you can get away with writing to the .py file on the OSs which would prevent modifying an open file.
Response to those who want to use a path relative to the script file: That file may not live in a place that is writable. Also: lrh9: os.path.dirname(sys.argv[0]) fails if the script was invoked via a symbolic link.
For unix-like OSs, the best option (still not entirely foolproof) is to use os.getenv('HOME') and create a file there. To add suspenders to the belt, fail over to a tmp location if there is no HOME or it isn't writable. A file whose name starts with '.' will not be seen by most users most of the time. For Windows OSs,that will work too, but storing the datum in the user's registry is the way the OS expects things to be done.
griswolf
Veteran Poster
1,165 posts since Apr 2010
Reputation Points: 344
Solved Threads: 256
In windows .directory is slightly nasty as the name can not be edited in Explorer and the directory is visible in Windows.
Yes the meta-programming is difficult to do in disciplined way but have its uses, mostly by way of using eval in program generated structures or executing fully program generated code (for example testing of genetic programming program for fitness). Generally it is stupid idea however to pick a piece of code in main module and do transformation to code, only to not have external files. You can only do simple open('config').read() and there is your value minus maybe conversion to number.
pyTony
pyMod
5,359 posts since Apr 2010
Reputation Points: 782
Solved Threads: 852
lrh9: Also, cluttering a home folder with various settings files doesn't seem like a good idea. It violates the principles of organization and privacy. On the contrary, it nicely matches the principles of organization and privacy: If you and I both run the program on the same computer, we should have individual and private settings. (Some subdirectory of) $HOME is the normal, therefore organized, place to put such config files. Since I can adjust my own file permissions in $HOME, I also have as much privacy about this as I prefer.
If, on the other hand, the program should run as a daemon (unix terminology) or (I think) "service" (Windows terminology), then obviously, $HOME is the wrong place (whose $HOME?). In that case, the usual practice (unix-like OSs) is to put the config file in an /etc directory. I think that the Windows practice is for these to be in the registry and to provide some editor function as needed. (Providing an options editor applies, more or less equally, to most "user friendly" OSs.)
lrh9: You seem to know about symbolic links. If the path read from a link is an absolute path will it be a complete path or will it lack a root? I don't know what a "complete" path is. I put this program in one place, provided a symbolic link in another place on my PATH and invoked it a variety of ways:
#!/usr/bin/env python
import os
import sys
print ("%s: %s"%(sys.argv[0],os.path.dirname(sys.argv[0])))
- Invoked on my PATH by its own name (ar.py):
./ar.py: . note the added '.' which is on my PATH - Invoked on my PATH by its symlink (WOO):
/Users/griswolf/bin/WOO: /Users/griswolf/bin note the added '/Users/griswolf/bin' which is on my path - Invoked off my path by name (mysite/ar.py):
mysite/ar.py: mysite note no added directory - Invoked off my path by symlink(bin/WOO):
bin/WOO: bin note no added directory
If you want the absolute path, which in my opinion is always safest, then you should use os.path.abspath(anypath)
griswolf
Veteran Poster
1,165 posts since Apr 2010
Reputation Points: 344
Solved Threads: 256
OK. So to feel 'natural' to the user, config files should go in an OS dependent place. I'll take your word for the Windows "natural place". In unix-like OSs, one natural place is $HOME/.something which might also be considered 'classic unix' layout. OS/X seems to like $HOME/Library/Application_name/... or $HOME/Library/Application Support/Application_name
I did not try your second code as I disagree with the usefulness (per my belief that usually should be user-centric storage). It looks a little more complex than I think it would need to be, but I didn't work it out for myself, so it might be perfect. I'm not sure about the relative symbolic link calculation: Probably right, but I would need to think it through a little harder.
griswolf
Veteran Poster
1,165 posts since Apr 2010
Reputation Points: 344
Solved Threads: 256