python - concision in a for loop without list comprehension -


please don't laugh. i'm trying write simple script replace hostname , ip of base vm. have working version of this, i'm trying make more readable , concise. i'm getting syntax error when trying code below. trying make these list comprehensions, since file types, won't work. in advance.

try:    old_network = open("/etc/sysconfig/network", "r+")    new_network = open("/tmp/network", "w+")    replacement = "hostname=" + str(sys.argv[1]) + "\n"     shutil.copyfile('/etc/sysconfig/network', '/etc/sysconfig/network.setup_bak')    line in old_network: new_network.write(line) if not re.match(("hostname"), line)    line in old_network: new_network.write(replacement) if re.match(("hostname"), line)    os.rename("/tmp/network","/etc/sysconfig/network")    print 'hostname set to', str(sys.argv[1]) except ioerror, e:     print "error %s" % e     pass 

you using odd syntax here:

for line in old_network: new_network.write(line) if not re.match(("hostname"), line) line in old_network: new_network.write(replacement) if re.match(("hostname"), line) 

you need reverse if statement there, , put these on separate lines; have combine loops, lets simplify if statements too:

for line in old_network:     if not re.match("hostname", line):         new_network.write(line)      else:         new_network.write(replacement) 

you cannot loop on input file twice (your second loop wouldn't file has been read in full).

next, want use open file objects context managers (using with) make sure closed properly, whatever happens. can drop + file modes, not using files in mixed mode, , backup copy best done first before opening reading , writing yet.

there no need use regular expression here; testing presence of straightforward simple string, 'hostname' in line do, or perhaps line.strip().startswith('hostname') make sure line starts hostname.

use tempfile module create temporary file name won't conflict:

from tempfile import namedtemporaryfile  shutil.copyfile('/etc/sysconfig/network', '/etc/sysconfig/network.setup_bak')  replacement = "hostname={}\n".format(sys.argv[1]) new_network = namedtemporaryfile(mode='w', delete=false)  open("/etc/sysconfig/network", "r") old_network, new_network:     line in old_network:         if line.lstrip().startswith('hostname'):             line = replacement         new_network.write(line)   os.rename(new_network.name, "/etc/sysconfig/network") print 'hostname set {}'.format(sys.argv[1]) 

you can simplify further using fileinput module, lets replace file contents printing; supports creating backup file natively:

import fileinput import sys  replacement = "hostname={}\n".format(sys.argv[1])  line in fileinput('/etc/sysconfig/network', inplace=true, backup='.setup_bak'):     if line.lstrip().startswith('hostname'):         line = replacement     sys.stdout.write(line)  print 'hostname set {}'.format(sys.argv[1]) 

that's 6 lines of code (not counting imports) versus 12. can squash down 4 using conditional expression, not sure if makes things more readable:

for line in fileinput('/etc/sysconfig/network', inplace=true, backup='.setup_bak'):     sys.stdout.write(replacement if line.lstrip().startswith('hostname') else line) 

Comments

Popular posts from this blog

linux - xterm copying to CLIPBOARD using copy-selection causes automatic updating of CLIPBOARD upon mouse selection -

c++ - qgraphicsview horizontal scrolling always has a vertical delta -