I'm new to Python and i'd like to build a script (Python 3) to test electronic modules and save log files.
I'd like to save the logfiles in the following format:
201410log.txt (yearmonthlog.txt)
This is done with the code:
import os
logfile=open(time.strftime('%Y%mlog.txt'), 'a')
logfile.write('This is a test\n\n\n')
This way, every month a new log file is created.
However, i'd like the logfiles to be in in a subdirectory (\logs).
I tried approaches like
logfile=open(time.strftime('\logs\%Y%mlog.txt'), 'a')
and similar things but i couldnt get any of them to work.
I searched trough other questions on stackoverflow (for example: Relative paths in Python ) and elsewhere in the internet, but i couldnt find the right solution.
Could someone point me in the right direction?
(sorry for any mistakes/spelling errors, i'm no native english speaker)
Remove the leading backslash. It makes the path absolute. Beside that, you need to escape a backslash.
logfile = open(time.strftime('logs\\%Y%mlog.txt'), 'a')
or use r'raw string literal':
logfile = open(time.strftime(r'logs\%Y%mlog.txt'), 'a')
For your current path string literal, it does not make problem. But paths like 'a\nb' will not work because \n is interpreted as newline instead of a literal backslash and n.
Related
I've been working on a program that reads out an specific PDF and converts the data to an Excel file. The program itself already works, but while trying to refine some aspects I ran into a problem. What happens is the modules I'm working with read directories with simple slashes dividing each folder, such as:
"C:/Users/UserX"
While windows directories are divided by backslashes, such as:
"C:\Users\UserX"
I thought using a simple replace would work just fine:
directory.replace("\" ,"/")
But whenever I try to run the program, the \ isn't identified as a string. Instead it pops up as orange in the IDE I'm working with (PyCharm). Is there anyway to remediate this? Or maybe another useful solution?
In general you should work with the os.path package here.
os.getcwd() gives you the current directory, you can add a subfolder of it via more arguments, and put the filename last.
import os
path_to_file = os.path.join(os.getcwd(), "childFolder", filename)
In Python, the '\' character is represented by '\\':
directory.replace("\\" ,"/")
Just try adding another backslash.
First of all you need to pass "C:\Users\UserX" as a raw string. Use
directory=r"C:\Users\UserX"
Secondly, suppress the backslash using a second backslash.
directory.replace("\\" ,"/")
All of this is required as in python the backslash (\) is a special character known as an escape character.
Try this:
import os
path = "C:\\temp\myFolder\example\\"
newPath = path.replace(os.sep, '/')
print(newPath)
Output:<< C:/temp/myFolder/example/ >>
Given this simple code, I receive faulty paths if the userfolder contains any special characters. For example the returned path is expected to be "C:\Users\Aoë\", but the ë is instead shown as a ‰ or a \u2030 depending on what is done with encoding. This then messes up the rest of my code because of attempts to write to nonexistent paths.
I ran into this problem trying to run kivy, but it seems to be happening globally.
from pathlib import Path
home = str(Path.home())
print(home)
I've spent quite some time, but haven't been able to reach a solution. This is with the latest python, x64 on windows with eclipse. No matter what I do, I cannot get python to handle special characters properly.
Try 'r' tag at the beginning, it ignores the special characters:
home = r'%s'%str(Path.home())
I'm trying to find all *.txt files in a directory with glob(). In some cases, glob.glob('some\path\*.txt') gives an empty string, despite existing files in the given directories. This is especially true, if path is all lower-case or numeric.
As a minimal example I have two folders a and A on my C: drive both holding one Test.txt file.
import glob
files1 = glob.glob('C:\a\*.txt')
files2 = glob.glob('C:\A\*.txt')
yields
files1 = []
files2 = ['C:\\A\\Test.txt']
If this is by design, is there any other directory name, that leads to such unexpected behaviour?
(I'm working on win 7, with Python 2.7.10 (32bit))
EDIT: (2019) Added an answer for Python 3 using pathlib.
The problem is that \a has a special meaning in string literals (bell char).
Just double backslashes when inserting paths in string literals (i.e. use "C:\\a\\*.txt").
Python is different from C because when you use backslash with a character that doesn't have a special meaning (e.g. "\s") Python keeps both the backslash and the letter (in C instead you would get just the "s").
This sometimes hides the issue because things just work anyway even with a single backslash (depending on what is the first letter of the directory name) ...
I personally avoid using double-backslashes in Windows and just use Python's handy raw-string format. Just change your code to the following and you won't have to escape the backslashes:
import glob
files1 = glob.glob(r'C:\a\*.txt')
files2 = glob.glob(r'C:\A\*.txt')
Notice the r at the beginning of the string.
As already mentioned, the \a is a special character in Python. Here's a link to a list of Python's string literals:
https://docs.python.org/2/reference/lexical_analysis.html#string-literals
As my original answer attracted more views than expected and some time has passed. I wanted to add an answer that reliably solves this kind of problems and is also cross-plattform compatible. It's in python 3 on Windows 10, but should also work on *nix systems.
from pathlib import Path
filepath = Path(r'C:\a')
filelist = list(filepath.glob('*.txt'))
--> [WindowsPath('C:/a/Test.txt')]
I like this solution better, as I can copy and paste paths directly from windows explorer, without the need to add or double backslashes etc.
I have a problem when programming in Python running under Windows. I need to work with file paths, that are longer than 256 or whatsathelimit characters.
Now, I've read basically about two solutions:
Use GetShortPathName from kernel32.dll and access the file in this way.
That is nice, but I cannot use it, since I need to use the paths in a way
shutil.rmtree(short_path)
where the short_path is a really short path (something like D:\tools\Eclipse) and the long paths appear in the directory itself (damn Eclipse plugins).
Prepend "\\\\?\\" to the path
I haven't managed to make this work in any way. The attempt to do anything this way always result in error WindowsError: [Error 123] The filename, directory name, or volume label syntax is incorrect: <path here>
So my question is: How do I make the 2nd option work? I stress that I need to use it the same way as in the example in option #1.
OR
Is there any other way?
EDIT: I need the solution to work in Python 2.7
EDIT2: The question Python long filename support broken in Windows does give the answer with the 'magic prefix' and I stated that I know it in this question. The thing I do not know is HOW do I use it. I've tried to prepend that to the path but it just failed, as I've written above.
Well it seems that, as always, I've found the answer to what's been bugging me for a week twenty minutes after I seriously ask somebody about it.
So I've found that I need to make sure two things are done correctly:
The path can contain only backslashes, no forward slashes.
If I want to do something like list a directory, I need to end the path with a backslash, otherwise Python will append /*.* to it, which is a forward slash, which is bad.
Hope at least someone will find this useful.
Let me just simplify this for anyone looking for a straight answer:
For python < 3: Path needs to be unicode, prepend string with u like u'C:\\path\\to\\file'
Path needs to start with \\\\?\\ (which is escaped into \\?\) like u'\\\\?\\C:\\path\\to\\file'
No forward slashes only backslashes: / --> \\
It has to be an absolute path; it does not work for relative paths
py 3.8.2
# Fix long path access:
import ntpath
ntpath.realpath = ntpath.abspath
# Fix long path access.
In my case, this solved the problem of running a script from a long path.
(https://developers.google.com/drive/api/v3/quickstart/python)
But this is not a universal fix.
It looks like the ntpath.realpath implementation has problems. This code replaced it with a dummy.
it works for me
import os
str1=r"C:\Users\manual\demodfadsfljdskfjslkdsjfklaj\inner-2djfklsdfjsdklfj\inner3fadsfksdfjdklsfjksdgjl\inner4dfhasdjfhsdjfskfklsjdkjfleioreirueewdsfksdmv\anotherInnerfolder4aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\5qbbbbbbbbbbbccccccccccccccccccccccccsssssssssssssssss\tmp.txt"
print(len(str1)) #346
path = os.path.abspath(str1)
if path.startswith(u"\\\\"):
path=u"\\\\?\\UNC\\"+path[2:]
else:
path=u"\\\\?\\"+path
with open(path,"r+") as f:
print(f.readline())
if you get a long path(more then 258 char) issue in windows then try this .
I have a wxPython application. I am taking in a directory path from a textbox using GetValue().
I notice that while trying to write this string to a variable:
"C:\Documents and Settings\tchan\Desktop\InputFile.xls",
python sees the string as
'C:\\Documents and Settings\tchan\\Desktop\\InputFile.xls' (missing a slash between "Settings" and "UserName).
More info:
The directory path string is created by the "open file" dialog, which creates a standard 'choose file' dialog you see in any 'open' function in a text processor. The string is written to a textbox and read later when the main thread begins (in case the user wants to change it).
EDIT: I realise that the problem comes from the '\t' being seen as a "tab" instead of normal forward slash. However I don't know how to work past this, since
I suspect there's a different way to get that path from wx that would avoid this issue, since it seems like this would be a fairly common problem. That said, there are a few ways to fix a mangled path like you describe, by converting the string you have to a raw string.
rawpath = "%r" % path
The resulting rawpath will likely be somewhat messy since it will probably add extra escapes to the backslashes and give you something like:
"'C:\\\\Documents and Settings\\tchan\\\\Desktop\\\\InputFile.xls'"
It seems like os.path.normpath will clean that up though.
import os.path
os.path.normpath(rawpath)
not saying this is the correct solution, but you can
x = "C:\tmp".encode('string-escape')
x
'C:\\tmp'
better, if you are using the file dialog
os.path.join(dlg.GetDirectory(),dlg.GetFilename())
where dlg is your dialog
You have to escape the slashes. \\ will store a literal \ in the string:
path = "C:\\Documents and Settings\\tchan\\Desktop\\InputFile.xls"