Я полагаю, вам не хватает импорта библиотеки Salesforce
,
*** Settings ***
Resource cumulusci/robotframework/Salesforce.robot
Также, пожалуйста, убедитесь, что необходимый пакет Python уже установлен.
Одна проблема - то, что существует состояние состязания в Вашем выше кода, так как существует разрыв между тестированием на существование и созданием файла. Могут быть последствия безопасности к этому (думайте о ком-то, злонамеренно вставляя символьную ссылку на чувствительный файл, который они не смогли бы перезаписать, но Ваша программа, работающая с более высоким полномочием, могла), Нападения как они состоят в том, почему вещи как os.tempnam () удерживаются от использования.
Для обхождения его лучший подход должен на самом деле попробовать, создают файл таким способом, которым Вы получите исключение, если это перестанет работать, и на успехе, возвратите на самом деле открытый объект файла. Это может быть сделано с более низким уровнем os.open функции путем передачи обоих OS. O_CREAT и OS. Флаги O_EXCL. После того, как открытый, возвратите фактический файл (и дополнительно имя файла), Вы создаете. Например, вот Ваш код, измененный для использования этого подхода (возвращающийся (файл, имя файла) кортеж):
def unique_file(file_name):
counter = 1
file_name_parts = os.path.splitext(file_name) # returns ('/path/file', '.ext')
while 1:
try:
fd = os.open(file_name, os.O_CREAT | os.O_EXCL | os.O_RDRW)
return os.fdopen(fd), file_name
except OSError:
pass
file_name = file_name_parts[0] + '_' + str(counter) + file_name_parts[1]
counter += 1
[Редактирование] На самом деле, лучший путь, который обработает вышеупомянутые проблемы для Вас, состоит в том, чтобы, вероятно, использовать tempfile модуль, хотя можно потерять некоторый контроль над именованием. Вот пример использования его (хранение подобного интерфейса):
def unique_file(file_name):
dirname, filename = os.path.split(file_name)
prefix, suffix = os.path.splitext(filename)
fd, filename = tempfile.mkstemp(suffix, prefix+"_", dirname)
return os.fdopen(fd), filename
>>> f, filename=unique_file('/home/some_dir/foo.txt')
>>> print filename
/home/some_dir/foo_z8f_2Z.txt
единственный недостаток с этим подходом - то, что Вы будете всегда получать имя файла с некоторыми случайными символами в нем, поскольку нет никакой попытки создать неизмененный файл (/home/some_dir/foo.txt) сначала. Можно также хотеть посмотреть на tempfile. TemporaryFile и NamedTemporaryFile, который сделает вышеупомянутое и также автоматически удалит из диска при закрытии.
Если Вы хотите читаемые имена, это похоже на хорошее решение.
существуют стандартные программы для возврата уникальных имен файлов для, например, временных файлов, но они производят длинные случайно выглядящие имена.
если Вы не заботитесь об удобочитаемости, uuid.uuid4 () Ваш друг.
import uuid
def unique_filename(prefix=None, suffix=None):
fn = []
if prefix: fn.extend([prefix, '-'])
fn.append(str(uuid.uuid4()))
if suffix: fn.extend(['.', suffix.lstrip('.')])
return ''.join(fn)
Два небольших изменения...
base_name, ext = os.path.splitext(file_name)
Вы получаете два результата с отличным значением, даете им отличные имена.
file_name = "%s_%d%s" % (base_name, str(counter), ext)
Это не быстрее или значительно короче. Но, когда Вы хотите изменить свой шаблон имени файла, шаблон находится на одном месте, и немного легче работать с.
Да, это - хорошая стратегия читаемых но уникальных имен файлов.
Одно важное изменение : необходимо заменить os.path.isfile
os.path.lexists
! Как это записано прямо сейчас, если будет каталог, названный/foo/bar.baz, то Ваша программа попытается перезаписать это с новым файлом (который не будет работать)... с тех пор isfile
только проверки на файлы и не каталоги. lexists
проверки на каталоги, символьные ссылки, и т.д.... в основном, если существует какая-либо причина, что имя файла не могло быть создано.
РЕДАКТИРОВАНИЕ: @Brian дал лучший ответ, который более безопасен и устойчив с точки зрения условий состязания.
Как насчет
def ensure_unique_filename(orig_file_path):
from time import time
import os
if os.path.lexists(orig_file_path):
name, ext = os.path.splitext(orig_file_path)
orig_file_path = name + str(time()).replace('.', '') + ext
return orig_file_path
время () возвращает текущее время в миллисекундах. объединенный с исходным именем файла, это довольно уникально даже в сложных многопоточных случаях.