Возможно, потому, что в std :: map нет оператора const []. оператор [] добавит элемент, который вы ищете, если он его не найдет. Поэтому используйте метод find (), если вы хотите искать без возможности добавления.
Это пытается быть немного более свободным от гонки, чем другие решения. (Ключевое слово with
является новым в Python 2.5.)
import os
def touch(fname, times=None):
with open(fname, 'a'):
os.utime(fname, times)
Грубо эквивалентно этому.
import os
def touch(fname, times=None):
fhandle = open(fname, 'a')
try:
os.utime(fname, times)
finally:
fhandle.close()
Теперь, чтобы действительно сделать его без гонок, вам нужно использовать futimes
и изменить временную метку открытого дескриптора файла вместо того, чтобы открывать файл, а затем изменять временную метку на имени файла (которое могло быть переименовано). К сожалению, Python, похоже, не предоставляет способ вызова futimes
без прохождения ctypes
или подобного ...
EDIT
Как отмечено Nate Parsons , Python 3.3 добавит , указав дескриптор файла (когда os.supports_fd
) к функциям, таким как os.utime
, который будет использовать syscall futimes
вместо utimes
syscall под капотом. Другими словами:
import os
def touch(fname, mode=0o666, dir_fd=None, **kwargs):
flags = os.O_CREAT | os.O_APPEND
with os.fdopen(os.open(fname, flags=flags, mode=mode, dir_fd=dir_fd)) as f:
os.utime(f.fileno() if os.utime in os.supports_fd else fname,
dir_fd=None if os.supports_fd else dir_fd, **kwargs)
Сложность (возможно, ошибка):
def utime(fname, atime=None, mtime=None)
if type(atime) is tuple:
atime, mtime = atime
if atime is None or mtime is None:
statinfo = os.stat(fname)
if atime is None:
atime = statinfo.st_atime
if mtime is None:
mtime = statinfo.st_mtime
os.utime(fname, (atime, mtime))
def touch(fname, atime=None, mtime=None):
if type(atime) is tuple:
atime, mtime = atime
open(fname, 'a').close()
utime(fname, atime, mtime)
Это также позволяет установить время доступа или модификации, например, GNU touch.
with open(fn,'a'): pass
или альтернатива open(fn, 'a').close()
не изменяют время изменения, используя Python 2.7.5 в Red Hat 7 (файловая система - XFS). На моей платформе эти решения просто создают пустой файл, если он не существует. : - /
– olibre
6 June 2017 в 13:58
Почему бы не попробовать это?:
import os
def touch(fname):
try:
os.utime(fname, None)
except OSError:
open(fname, 'a').close()
Я считаю, что это устраняет любое состояние гонки, которое имеет значение. Если файл не существует, будет выбрано исключение.
Единственное возможное условие гонки здесь - если файл создается до вызова функции open (), но после os.utime (). Но это не имеет значения, потому что в этом случае время модификации будет таким, как ожидалось, поскольку оно должно было произойти во время вызова touch ().
Похоже, что это новое, как у Python 3.4 - pathlib
.
from pathlib import Path
Path('path/to/file.txt').touch()
Это создаст file.txt
на пути.
-
Path.touch (mode = 0o777, exist_ok = True)
Создайте файл по данному пути. Если задан режим, он сочетается с значением «umask» процесса, чтобы определить режим файла и флаги доступа. Если файл уже существует, функция будет успешной, если exist_ok истинно (и время его модификации обновляется до текущего времени), в противном случае FileExistsError будет поднят.
Path('/some/path').mkdir()
, если каталог, содержащий файл touch()
ed, еще не существует.
– JacobIRR
7 July 2018 в 05:04
def touch(fname):
if os.path.exists(fname):
os.utime(fname, None)
else:
open(fname, 'a').close()
open()
, содержимое файла будет усечено. Вместо этого предложите использовать режим 'a'
.
– Greg Hewgill
21 July 2009 в 10:25
open(fname, 'a').close()
не изменится.
– SilentGhost
21 July 2009 в 11:40
os.utime()
там для ранее существовавших файлов.
– Greg Hewgill
21 July 2009 в 11:43
Может показаться логичным создать строку с требуемыми переменными и передать ее в os.system:
touch = 'touch ' + dir + '/' + fileName
os.system(touch)
Это неадекватно несколькими способами (например, он не обрабатывает пробелы), так что не делайте этого.
Более надежным методом является использование подпроцесса:
subprocess.call(['touch', os.path.join(dirname, fileName)])
Хотя это намного лучше, чем использование подоболочки (с os.system), это по-прежнему подходит только для быстрого и грязного сценариев; используйте принятый ответ для кросс-платформенных программ.
subprocess.call(['touch', os.path.join(dirname, fileName)])
намного лучше, чем использование подоболочки (с os.system
). Но все же, используйте это только для быстрых и грязных сценариев, используйте принятый ответ для кросс-платформенных программ.
– ayke
8 July 2012 в 11:58
touch
не является кросс-платформенной доступной командой (например, Windows)
– Mike T
21 May 2018 в 06:23
Упрощенный:
def touch(fname):
open(fname, 'a').close()
os.utime(fname, None)
open
гарантирует, что там есть файл utime
гарантирует обновление временных меток Теоретически, возможно, кто-то удалит файл после open
, вызывая утилизацию для возникновения исключения. Но, возможно, все в порядке, так как случилось что-то плохое.
"open (имя_файла, 'a'). close ()" не работает для меня в Python 2.7 на Windows. «os.utime (имя_файла, нет)» отлично работало.
Кроме того, мне пришлось рекурсивно обращаться ко всем файлам в каталоге с датой, более старой, чем какая-либо дата. Я создал hte follow, основанный на очень полезном ответе ephemient.
def touch(file_name):
# Update the modified timestamp of a file to now.
if not os.path.exists(file_name):
return
try:
os.utime(file_name, None)
except Exception:
open(file_name, 'a').close()
def midas_touch(root_path, older_than=dt.now(), pattern='**', recursive=False):
'''
midas_touch updates the modified timestamp of a file or files in a
directory (folder)
Arguements:
root_path (str): file name or folder name of file-like object to touch
older_than (datetime): only touch files with datetime older than this
datetime
pattern (str): filter files with this pattern (ignored if root_path is
a single file)
recursive (boolean): search sub-diretories (ignored if root_path is a
single file)
'''
# if root_path NOT exist, exit
if not os.path.exists(root_path):
return
# if root_path DOES exist, continue.
else:
# if root_path is a directory, touch all files in root_path
if os.path.isdir(root_path):
# get a directory list (list of files in directory)
dir_list=find_files(root_path, pattern='**', recursive=False)
# loop through list of files
for f in dir_list:
# if the file modified date is older thatn older_than, touch the file
if dt.fromtimestamp(os.path.getmtime(f)) < older_than:
touch(f)
print "Touched ", f
# if root_path is a file, touch the file
else:
# if the file modified date is older thatn older_than, touch the file
if dt.fromtimestamp(os.path.getmtime(f)) < older_than:
touch(root_path)
Вот код, который использует ctypes (тестируется только в Linux):
from ctypes import *
libc = CDLL("libc.so.6")
# struct timespec {
# time_t tv_sec; /* seconds */
# long tv_nsec; /* nanoseconds */
# };
# int futimens(int fd, const struct timespec times[2]);
class c_timespec(Structure):
_fields_ = [('tv_sec', c_long), ('tv_nsec', c_long)]
class c_utimbuf(Structure):
_fields_ = [('atime', c_timespec), ('mtime', c_timespec)]
utimens = CFUNCTYPE(c_int, c_char_p, POINTER(c_utimbuf))
futimens = CFUNCTYPE(c_int, c_char_p, POINTER(c_utimbuf))
# from /usr/include/i386-linux-gnu/bits/stat.h
UTIME_NOW = ((1l << 30) - 1l)
UTIME_OMIT = ((1l << 30) - 2l)
now = c_timespec(0,UTIME_NOW)
omit = c_timespec(0,UTIME_OMIT)
# wrappers
def update_atime(fileno):
assert(isinstance(fileno, int))
libc.futimens(fileno, byref(c_utimbuf(now, omit)))
def update_mtime(fileno):
assert(isinstance(fileno, int))
libc.futimens(fileno, byref(c_utimbuf(omit, now)))
# usage example:
#
# f = open("/tmp/test")
# update_mtime(f.fileno())
file
была удалена из Python 3, и вместо этого нужно использоватьopen
. Я полностью пропустил это, потому что подсветка синтаксиса редактора, который я использую (gedit), по-прежнему нацелена на Python 2. – Bart 24 January 2014 в 10:53