2016-06-23 7 views
1

Есть ли еще более удобный способ записи в файлы python, чем использование чтения/записи для любого файла (например, файлы txt и т. Д.).Python - запись в файлы python?

Я имею в виду, что python знает, что на самом деле представляет собой структуру файла python, поэтому, если мне нужно записать в нее, возможно, есть еще более удобный способ сделать это?

Если нет такой способ (или это слишком сложно), то, что будет лучший способ обычно изменить файл питона только с помощью обычного write (пример ниже)?

У меня есть много этих файлов в моих подкаталогов называется:

__config__.py

Эти файлы используются в качестве конфигурации. И у них есть незадействованный словарь питона, например:

{ 
    'name': 'Hello', 
    'version': '0.4.1' 
} 

Так что мне нужно сделать, это написать для всех тех, кто __config__.py файлов новой версии (например, 'version': '1.0.0').

Update

Чтобы быть более конкретным, учитывая, что есть питон файл с содержанием, как это:

# Some important comment 
# Some other important comment 
{ 
'name': 'Hello', 
'version': '0.4.1' 
} 
# Some yet another important comment 

Теперь работает некоторый питон скрипт, он должен написать в файл питон модифицирующим дал словарь и после записи, вывод должен быть таким:

# Some important comment 
# Some other important comment 
{ 
'name': 'Hello', 
'version': '1.0.0' 
} 
# Some yet another important comment 

Так, другими словами, писать следует o nly изменить version ключевое значение, и все остальное должно быть сохранено, как было до написания.

+0

поскольку контент - это словарь, возможно, вы можете превратить его в json и сделать 'json.dump()'? – scarecrow

+0

Ну, вы можете ['literal_eval()'] (https://docs.python.org/3/library/ast.html#ast.literal_eval) литералы python, которые содержатся в вашем файле. Тем не менее, запись в симпатичном формате. Может быть, [pprint] (https://docs.python.org/3/library/pprint.html) может помочь. –

+0

Возможно, это может быть полезно? http://stackoverflow.com/questions/768634/parse-a-py-file-read-the-ast-modify-it-then-write-back-the-modified-source-c – Jaxian

ответ

0

Я придумал решение. Это не очень чисто, но это работает. Если у кого-то есть лучший ответ, напишите об этом.

content = '' 
file = '__config__.py' 
with open(file, 'r') as f: 
    content = f.readlines() 
    for i, line in enumerate(content): 
     # Could use regex too here 
     if "'version'" in line or '"version"' in line: 
      key, val = line.split(':') 
      val = val.replace("'", '').replace(',', '') 
      version_digits = val.split('.') 
      major_version = float(version_digits[0]) 
      if major_version < 1: 
       # compensate for actual 'version' substring 
       key_end_index = line.index('version') + 8 
       content[i] = line[:key_end_index] + ": '1.0.0',\n" 
with open(file, 'w') as f: 
    if content: 
     f.writelines(content) 
+0

Почему нет 'sed'? ;) – scarecrow

+0

Что такое sed? :-) – Andrius

+0

'sed' - это утилита * nix, которая может использоваться для текстовых преобразований, но более известна для поиска и замены. http://www.brunolinux.com/02-The_Terminal/Find_and%20Replace_with_Sed.html. Если вы просто хотите заменить номера версий, вот команда сделать это 'sed -e 's /' version ':' 0.4.1 '/' version ':' 1.0.0 '/ g" test.cnf> new .cnf' – scarecrow

0

Для того, чтобы изменить конфигурационный файл, вы можете просто сделать STH так:

import fileinput 

lines = fileinput.input("__config__.py", inplace=True) 
nameTag="\'name\'" 
versionTag="\'version\'" 
name="" 
newVersion="\'1.0.0\'" 
for line in lines: 
    if line[0] != "'": 
     print(line) 
    else: 
     if line.startswith(nameTag): 
      print(line) 
      name=line[line.index(':')+1:line.index(',')] 
     if line.startswith(versionTag): 
      new_line = versionTag + ": " + newVersion 
      print(new_line) 

Обратите внимание, что функция печати здесь на самом деле пишет в файл. для получения более подробной информации о том, как функция печати записывается для вас, см. here

Надеюсь, это поможет.

+1

'fileinput' очень опасно использовать с' inplace', вы не используете его в диспетчере контекста, поэтому потенциальный стандартный вывод перенаправляется на этот файл, если в цикле for происходит исключение. Кроме того, строки '.strip()' ing вы также удаляете любой отступ, который разбивает код python на этих строках. Кроме того, срез очень сильно зависит от точной фразы –

+0

, я на самом деле не заметил, что зачистка может сломать отступ python на первом месте. Таким образом, +1 для вашего комментария! – Soheil

+0

Хотя, если код содержит * только * словарь и некоторые комментарии, то нет отступов для разрыва. –