Использование NamedTemporaryFile

with NamedTemporaryFile(suffix='.shp').name as tmp_shp:
    df.to_file(tmp_shp)

В приведенном выше коде я получаю эту ошибку:

AttributeError: __enter__

Как я могу использовать именованный временный файл с помощью оператора with? и поскольку tmp_shp - это всего лишь путь, остается ли он доступным вне with?

Почему вы пытаетесь использовать атрибут файла name в качестве диспетчера контекста?

user2357112 supports Monica 17.04.2018 03:29
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
1
2 264
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Вы используете атрибут name в качестве диспетчера контекста. Пытаться:

with NamedTemporaryFile(suffix='.shp') as tmp_shp:
    df.to_file(tmp_shp)

Вы должны использовать оператор with для самого NamedTemporaryFile, но не для его атрибута name.

with NamedTemporaryFile(suffix='.shp') as tmp_file:
    df.to_file(tmp_file)  # As temp_file is a file object, I think to_file should work?

И как официальный документ, tmp_file будет удален вне with, если вы не передадите delete=False в NamedTemporaryFile.

Это означает, что вам следует with NamedTemporaryFile(suffix='.shp', delete=False) as tmp_file:

Ответ принят как подходящий

Атрибут name - это строка; попытка получить к нему доступ в операторе with делает его управляемым ресурсом (а str не имеет концепции управления контекстом). Вам необходимо управлять самим NamedTemporaryFile и обращаться к name по мере необходимости:

with NamedTemporaryFile(suffix='.shp') as tmp_shp:
    df.to_file(tmp_shp.name)  # Access .name here, assuming you need a str

Если to_file принимает файловые объекты (я не могу найти документацию для такого метода), вы вообще избегаете использования .name (в любой строке).

Обновлять: Поскольку вы работаете в Windows, вы не можете открыть файл, открытый NamedTemporaryFile, с помощью delete=True (по умолчанию), пока NamedTemporaryFile не будет закрыт (что означает, что вы не можете использовать какие-либо данные, записанные в этот дескриптор файла, поскольку он удален, и вводит состояние гонки, даже если вы используете его исключительно для генерации уникального имени; файл удаляется в в этот момент, так что вы на самом деле просто создаете новый файл, но кто-то другой может подтолкнуть вас к созданию этого файла позже). Лучшее, что я могу предложить здесь, - это использовать его без поддержки удаления, чтобы получить уникальное имя, обернув его для принудительного удаления самостоятельно, например:

tmp_shp = None
try:
    with NamedTemporaryFile(suffix='.shp', delete=False) as tmp_shp:

        df.to_file(tmp_shp.name)  # Access .name here, assuming you need a str

        ... do any other stuff with the file ...
finally:
    if tmp_shp is not None:
        os.remove(tmp_shp.name)

Ага, это некрасиво. Здесь не так много хороших вариантов; NamedTemporaryFile принципиально не работает в Windows.

спасибо @ShadowRanger. Я получаю эту ошибку *** RuntimeError: Failed to open C:\Users\rk\AppData\Local\Temp\tmpz5c2fvlg.shp

user308827 17.04.2018 03:53

@ user308827: Ох, у вас Windows. Есть ... вопросы ... с NamedTemporaryFile в Windows. Краткая версия: вы не можете открыть его с помощью большинства программ, если вы не передадите delete=False при его создании (что удаляет большую часть точки), или вы используете его исключительно для создания уникального имени (и закройте его, прежде чем кто-либо другой использует Это).

ShadowRanger 17.04.2018 04:04

@ShadowRanger: Вы неправильно поняли (или, по крайней мере, исказили) тему проблемы. Проблема заключается в том, что вы не можете снова открыть файла, лежащего в основе NamedTemporaryFile, по имени, пока файл не будет закрыт, и для повторного открытия требуется delete=False, чтобы предотвратить автоматическое удаление файла при закрытии. Ваш ответ в настоящее время подразумевает, что NamedTemporaryFile с delete = True можно открыть после его закрытия; этого не может быть, так как к этому моменту файл исчез.

user2357112 supports Monica 17.04.2018 05:02

@ user2357112: Учитывая, что рассматриваемый API работает с файлом название, является пытается его повторно открыть. Я указывал, что единственный способ «повторно открыть» его с помощью delete=True - это закрыть его (что удаляет его в процессе), а затем снова открыть это имя (учитывая, что API использует имена, он предположительно способен создать файл); как уже упоминалось, закрытие / удаление его перед использованием имени вводит гонку, в которой кто-то другой может использовать это имя. В моем примере кода, который позволяет избежать этой проблемы, используется delete=False, чтобы избежать гонки, но взамен он должен заново реализовать автоматическое удаление с нуля, что является проблемой.

ShadowRanger 17.04.2018 05:14

В исходной формулировке не говорилось, что вы создадите новый файл, если попытаетесь открыть файл после закрытия с помощью delete=True. Ваша новая формулировка ... ну, она немного запутанно структурирована, но, по крайней мере, дает понять, что вы создаете новый файл. (Кроме того, по-видимому, вы может повторно открываете NamedTemporaryFile перед закрытием с помощью delete=False, поэтому либо OP в отчете о проблеме был неправильным, либо с тех пор что-то изменилось. Сначала я подумал, что это ошибка в вашем ответе.)

user2357112 supports Monica 17.04.2018 05:34

Другие вопросы по теме