У объекта 'tuple' нет атрибута 'replace' - PullRequest
0 голосов
/ 13 октября 2018

Я прошел предыдущие посты по этой ошибке.Но это не помогает мне.Поэтому я снова обращаю внимание.Код выглядит следующим образом.

import os
replacements = {':': '_', '+': '_'}

for fn in os.walk('/media/ambijat/Dataworld/f23/Dropbox/ttgis'):
    nn = fn
    for k, v in replacements.items():
        nn = nn.replace(str(k), str(v))
        if nn != fn:
             os.rename(fn, nn)

При запуске выдает ошибку 'tuple' object has no attribute 'replace' и, похоже, выдает ошибку.Я использую dict для замены специальных символов в именах файлов, например, [,&<>*?|\";+:'() ].Есть ли лучший способ сделать это.спасибо.

Ответы [ 3 ]

0 голосов
/ 13 октября 2018

Проблема в том, что строка

nn = nn.replace(str(k), str(v))

os.walk возвращает последовательность кортежей в форме (dirpath, dirnames, filenames) в соответствии с Документами Python .Итак, вы пытаетесь вызвать метод .replace() для кортежа, который выдает ошибку, потому что класс tuple не имеет такого метода.Я предполагаю, что вы хотели использовать метод str.replace().

Вот код, который должен работать (проверено на некоторых каталогах, которые я создал для этой цели на моей машине):

import os
replacements = {':': '_', '+': '_'}

for directory in os.walk('/media/ambijat/Dataworld/f23/Dropbox/ttgis'):
    filenames = directory[-1]

    for k, v in replacements.items():

        for filename in filenames:
            newname = filename.replace(k, v)

            if newname != filename:
                os.rename(directory[0]+'\\'+filename, directory[0]+'\\'+newname)
0 голосов
/ 13 октября 2018

В вашем первом фрагменте кода fn - это кортеж, так как os.walk() возвращает кортеж dirpath (строка), dirnames (список), имен файлов (список).Таким образом, когда он присваивается nn, nn становится кортежем, а использование nn.replace(k, v) в свою очередь не будет работать, потому что кортеж не имеет метода replace.

Во втором фрагменте кода., nn теперь равно fn[2] (список имен).К сожалению, в списке нет метода replace.Предполагая, что вы заменяете все : и + в своих именах файлов, вам необходимо выполнить цикл по каждому из этих имен файлов:

Другие вещи, которые я наблюдал и изменил в коде:

  • имена файлов, возвращаемые os.walk, не включают полный путь к файлу, что означает, что os.rename может не найти файл, если скрипт не запущен в том же каталоге, в котором вы переименовываете файлы,Поэтому я включил path во время переименования.
  • после os.rename, файл в каталоге будет переименован, но имя файла, который читал код, будет таким же.Таким образом, вы также должны изменить имя файла в коде.

Итак:

import os
replacements = {':': '_', '+': '_'}

for fn in os.walk('/media/ambijat/Dataworld/f23/Dropbox/ttgis'):
    path = fn[0]
    nn = fn[2]
    for filename in nn:
        newname = filename
        for k, v in replacements.items():
            newname = newname.replace(str(k), str(v))
            if newname != filename:
                 os.rename(os.path.join(path, filename), os.path.join(path, newname))
                 filename = newname

Хотя я бы вырезал еще одну строку кода через следующее предложение:

import os
replacements = {':': '_', '+': '_'}

for path, _, filenames in os.walk('/media/ambijat/Dataworld/f23/Dropbox/ttgis'):
    for filename in filenames:
        newname = filename
        for k, v in replacements.items():
            newname = newname.replace(k, v)
            if newname != filename:
                 os.rename(os.path.join(path, filename), os.path.join(path, newname))
                 filename = newname
0 голосов
/ 13 октября 2018

os.walk дает кортежи:

Для каждого каталога в дереве с корнем в вершине каталога (включая саму вершину) он выдает 3-кортеж (dirpath, dirnames, filenames) .

Чтобы извлечь только имя файла, используйте индексирование или распаковку последовательности.Любой из них будет работать:

nn = fn[-1]
nn = fn[2]
_, _, nn = fn

В качестве альтернативы, как указывает @AntonvBR, вы можете использовать распаковку последовательности в определении итерируемого цикла for:

for _, _, fn in os.walk('/media/ambijat/Dataworld/f23/Dropbox/ttgis'):
    nn = fn
    # as before..
...