2013-04-03 13 views
8

Piszę skrypt, aby przeanalizować wiele plików dziennika i zachować listę plików, które zostały przetworzone. Kiedy czytam listę plików do przetworzenia używam os.walk i uzyskać nazwy podobne do następujących:Python - Czy mogę (lub powinienem) zmienić os.path.sep?

C:/Users/Python/Documents/Logs\ServerUI04\SystemOut_13.01.01_20.22.25.log 

ten jest tworzony przez następujący kod:

filesToProcess.extend(os.path.join(root, filename) for filename in filenames if logFilePatternMatch.match(filename)) 

Wydaje się, że „root” wykorzystywane do przodu ukośniki jako separator (jestem w systemie Windows i znajduję to wygodniej), ale "filename" używa odwrotnych ukośników, więc kończę na niespójnej ścieżce do pliku, ponieważ zawiera mieszaninę ukośników naprzód i odwrotnie jako separatory.

Próbowałem ustawienie separatora z:

os.path.sep = "/" 

i

os.sep = "/" 

Przed .join ale wydaje się nie mieć wpływu. Zdaję sobie sprawę, że teoretycznie mogłem manipulować łańcuchem, ale dłuższy termin, jaki chciałbym, aby mój skrypt działał na Uniksie i Windowsie, wolałby, żeby był dynamiczny, jeśli to możliwe.

Czy brakuje mi czegoś?

Aktualizacja:

podstawie pomocnych odpowiedzi poniżej wygląda mój problem samemu sobie, dla wygody miałem ustawić początkową ścieżkę używaną jako root tak:

logFileFolder = ['C:/Users/Python/Documents/Logs'] 

Kiedy zmienił go do tego:

logFileFolder = ['C:\\Users\\Python\\Documents\\Logs'] 

Wszystko działa, a ścieżki wynikowych ścieżek wszystkich używają znaku "\" w całym tekście. Wygląda na to, że moje podejście było złe, ponieważ starałem się, aby Python zmieniał zachowanie, zamiast korygować to, co ustawiłem jako wartość.

Dziękujemy!

+2

Pójdę w opałach i powiedzieć, że ustawienie 'os.sep' prawdopodobnie nie jest w porządku rozwiązanie. –

+0

możliwy duplikat [Dlaczego nie os.path.join używać os.path.sep lub os.sep?] (Http://stackoverflow.com/questions/12086224/why-not-os-path-join-use-os -path-sep-or-os-sep) – BrenBarn

+0

Jak wskazuje na to zduplikowane pytanie, 'os.path' działa poprzez zaimportowanie' posixpath' lub 'ntpath' w zależności od twojego systemu operacyjnego. Co ciekawe, w kodzie źródłowym tych modułów można zobaczyć, że separator ścieżek jest zakodowany jako literał łańcuchowy wewnątrz funkcji 'join', więc nie będzie można go zmienić bez napisania własnej funkcji' join'. – BrenBarn

Odpowiedz

7

chciałbym trzymać palce off os.sep i używać os.path.normpath() w wyniku połączenia korzenia i Nazwa pliku:

filesToProcess.extend(os.path.normpath(os.path.join(root, filename)) 
      for filename in filenames if logFilePatternMatch.match(filename))  
1

Jesteś lepiej nie dotykać os.sep i os.path.sep jako nie są używane przez os.path.join. Możesz użyć os.path.normpath zgodnie z sugestią Anthona. Inną alternatywą jest mieć własną prostą ścieżkę dołączyć:

os.sep.join([i1,i2,i3])

4

używam '/'.join([path1, path2]) rozwiązać ten probelm, ponieważ „/” działa dobrze w systemach Windows i Linux.

+1

To przyda się jednak we wszystkich przypadkach. Na przykład 'explorer.exe' akceptuje tylko argumenty ścieżki określone przez' \ '. – minerz029

0

Wolałem następującą funkcję narzędzia.

from os.path import sep, join 

def pjoin(*args, **kwargs): 
    return join(*args, **kwargs).replace(sep, '/') 

Konwertuje obie odmiany (styl linuxowy i styl okna) do stylu linux. Zarówno system Windows, jak i Linux obsługują separator "/" w pythonie.

Odrzuciłem uproszczone os.sep.join (['str', 'str', 'str']), ponieważ nie uwzględnia istniejących separatorów. Weźmy następujący przypadek z sep.join vs wanilii dołączyć:

In[79]: os.sep.join(['/existing/my/', 'short', 'path']) 
Out[79]: '/existing/my/\\short\\path' 
In[80]: os.path.join('/existing/my/', 'short', 'path') 
Out[80]: '/existing/my/short\\path' 

Vanilla join może być naprawiony z sugerowana:

In[75]: os.path.normpath(os.path.join('/existing/my/', 'short', 'path')) 
Out[75]: '\\existing\\my\\short\\path' 

tej pory tak bóg. Ale potem wprowadzamy następujący scenariusz, w którym będziemy interakcji z linuxem z okien.

local_path = os.path.normpath(os.path.join('C:\\local\\base', 'subdir', 'filename.txt')) 
remote_path = os.path.normpath(os.path.join('/remote/base', 'subdir', 'filename.txt')) 
sftp_server.upload(local_path, remote_path) 

Powyższy wtedy zawieść, ponieważ serwer SFTP oczekuje „/” separator podczas os.path.normpath będzie na szyby do normalizacji „\”.

Stosując funkcję użytkową pjoin lub podobne, to będzie działać przekrój OS, www, ftp, itp

Powiązane problemy