Из документов есть на самом деле два (вроде три, если считать list
аргумент) способов сделать это:
import ConfigParser, os
config = ConfigParser.ConfigParser()
config.readfp(open('defaults.cfg'))
config.read(['site.cfg', os.path.expanduser('~/.myapp.cfg')])
версия filename
также позволяет передавать несколько имен файлов в и ConfigParser
автоматически дескриптор (игнорировать) отсутствующие файлы. Это обычная идиома для конфигурационных файлов, где у вас может быть файл конфигурации по умолчанию, а затем локально определенный.
Почему это не соответствует тому, что оно называется readfp
, но write
, а не writefp
...? Вы можете прочитать на своем history. Также here.
В конце концов, дизайны (и дизайнеры) не всегда идеальны, особенности не всегда пойманы, но как только он становится стандартным lib, интерфейс заморожен.
Мы можем посмотреть на ConfigParser
источник, чтобы увидеть, почему read()
с FileObject молча игнорируется:
def read(self, filenames):
"""Read and parse a filename or a list of filenames.
Files that cannot be opened are silently ignored; this is
designed so that you can specify a list of potential
configuration file locations (e.g. current directory, user's
home directory, systemwide directory), and all existing
configuration files in the list will be read. A single
filename may also be given.
Return list of successfully read files.
"""
if isinstance(filenames, basestring):
filenames = [filenames]
read_ok = []
for filename in filenames:
try:
fp = open(filename)
except IOError:
continue
self._read(fp, filename)
fp.close()
read_ok.append(filename)
return read_ok
О - ничего себе - это будет интересно!
Ваш fileobject не является basestring
, поэтому он предполагает, что он должен быть итерируемым. Затем он выполняет итерацию в файле fileobject. Это означает, что он читает ваш файл для списка имен файлов, которые он пытается открыть.
Например, я сделал файл f
и заполнил его a-g, каждая буква в строке. strace
показывает:
open("f", O_RDONLY) = 3
open("a\n", O_RDONLY) = -1 ENOENT (No such file or directory)
open("b\n", O_RDONLY) = -1 ENOENT (No such file or directory)
open("c\n", O_RDONLY) = -1 ENOENT (No such file or directory)
open("d\n", O_RDONLY) = -1 ENOENT (No such file or directory)
open("e\n", O_RDONLY) = -1 ENOENT (No such file or directory)
open("f\n", O_RDONLY) = -1 ENOENT (No such file or directory)
open("g\n", O_RDONLY) = -1 ENOENT (No such file or directory)
... и так как API предназначен игнорировать файлы, которые он не может открыть, он просто игнорирует ошибки.
Из документов,
Если ни один из указанных файлов не существует, то экземпляр ConfigParser будет содержать пустой набор данных.Приложение, которое требует начальных значений должны быть загружено из файла необходимо загрузить нужный файл или файлы, используя readfp() перед вызовом чтения() для любых дополнительных файлов:
Такого поведение достаточно удивительно, что я подал http://bugs.python.org/issue27351 чтобы они знали об этом краевом случае.
Вы прочитали [документацию] (https://docs.python.org/2/library/configparser.html#ConfigParser.RawConfigParser.read) и документацию для альтернативного метода readfp? – BrenBarn