I am currently writing a small networkchat in Python3. I want to include a function to save the users history. Now my user class contains a variable for name and I want to save the history-file in a folder which has the name of the user as its name.
So for example it roughly looks like that:
import os
import os.path
class User:
name = "exampleName"
PATH = './exampleName/History.txt'
def SaveHistory(self, message):
isFileThere = os.path.exists(PATH)
print(isFileThere)
So it is alwasy returning "false" until I create a folder called "exampleName".
Can anybody tell me how to get this working?
Thanks alot!
if you use relative paths for file or directory names python will look for them (or create them) in your current working directory (the $PWD variable in bash).
if you want to have them relative to the current python file, you can use (python 3.4)
from pathlib import Path
HERE = Path(__file__).parent.resolve()
PATH = HERE / 'exampleName/History.txt'
if PATH.exists():
print('exists!')
or (python 2.7)
import os.path
HERE = os.path.abspath(os.path.dirname(__file__))
PATH = os.path.join(HERE, 'exampleName/History.txt')
if os.path.exists(PATH):
print('exists!')
if your History.txt file lives in the exampleName directory below your python script.
Related
I have two exe files located at
C:\Users\Bella\Desktop\Folder\fuctions
I want to write a python script that would open them both from Desktop\Folder, The issue is I want to share this script with people and I won't know the name of their User,
Is there a way to execute the files while only knowing it will be in Folder\functions since I will always know that my script will be located in "Folder"
import os
os.startfile(r"C:\Users\Bella\Desktop\Folder\Dist\fuctions\Test.exe")
os.startfile(r"C:\Users\Bella\Desktop\Folder\Dist\fuctions\Test2.exe")
obviously that wont work when shared to friends
You can use relative path as mentioned in the comments or use:
import os
# get the directory of the file
dir = os.path.realpath('...')
# append the remainder of the path
path = os.path.join(dir, 'Dist\fuctions\Test.exe')
Use os.environ.get("USERNAME")
It gets the username of the user.
import os
username = os.environ.get("USERNAME")
os.startfile(f"C:\\Users\\{username}\\Desktop\\Folder\\Dist\\fuctions\\Test.exe")
os.startfile(r=f"C:\\Users\\{username}\\Desktop\\Folder\\Dist\\fuctions\\Test2.exe")
Or you can use os.getlogin()
import os
username = os.getlogin()
os.startfile(f"C:\\Users\\{username}\\Desktop\\Folder\\Dist\\fuctions\\Test.exe")
os.startfile(r=f"C:\\Users\\{username}\\Desktop\\Folder\\Dist\\fuctions\\Test2.exe")
Upvote if it works :)
I have the following structure
main.py
module/
properties.yaml
file.py
file.py relevant code:
def read_properties():
with open('properties.yaml') as file:
properties = yaml.load(file)
main.py relevant code:
from module import file
file.read_properties()
When read_properties() is called within main.py, I get the following error: FileNotFoundError: [Errno 2] No such file or directory: 'properties.yaml'
What is the recommended way of allowing my module to access the properties file even when imported?
Provide the absolute path to properties.yaml:
with open('/Users/You/Some/Path/properties.yaml') as file:
As JacobIRR said in his answer, it is best to use the absolute path to the file. I use the os module to construct the absolute path based on the current working directory. So for your code it would be something like:
import os
working_directory = os.path.dirname(__file__)
properties_file = os.path.join(working_directory, 'module', 'properties.yaml')
Based on answers from #JacobIRR and #BigGerman
I ended up using pathlib instead of os, but the logic is the same.
Here is the syntax with pathlib for those interested:
in file.py:
from pathlib import Path
properties_file = Path(__file__).resolve().parent/"properties.yaml"
with open(properties_file) as file:
properties = yaml.load(file)
I have a local variable in a Python script that creates temporary files using a path in my local C:\<User> folder:
Output_Feature_Class = "C:\\Users\\<User>\\Documents\\ArcGIS\\Default.gdb\\Bnd_"
However, I want to be able to share this script with others and don't want to have to hardcode a file path for each person using it. I basically want it to go to the same folder but <insert their User Name> example: C:\\TBrown\\Documents\\ArcGIS\Default.gdb\\Bnd_. I cannot seem to get just using
Output_Feature_Class = "..\\Documents\\ArcGIS\\Default.gdb\\Bnd_"
to work. Is there something I am missing?
Same answer as #Simon but with string formatting to condense it a bit and not attempt to concatenate strings together:
import getpass
Output_Feature_Class = "C:\\Users\\%s\\Documents\\ArcGIS\\Default.gdb\\Bnd_" % getpass.getuser()
As #Matteo Italia points out, Nothing guarantees you that user profiles are under c:\users, or that the user profile directory is called with the name of the user. So, perhaps addressing it by getting the user's home directory and building the path from there would be more advantageous:
from os.path import expanduser
Output_Feature_Class = "%s\\Documents\\ArcGIS\\Default.gdb\\Bnd_" % expanduser("~")
Update
As #Matteo Italia points out again, there may be cases when the Documents directory is located somewhere else by default. This may help find the path of the Documents of My Documents folder: reference (link)
from win32com.shell import shell
df = shell.SHGetDesktopFolder()
pidl = df.ParseDisplayName(0, None, "::{450d8fba-ad25-11d0-98a8-0800361b1103}")[1]
Output_Feature_Class = "%s\\ArcGIS\\Default.gdb\\Bnd_" % shell.SHGetPathFromIDList(pidl)
Rather than asking them to input their username, why not use getpass?
For example to get their username:
import getpass
a = getpass.getuser()
Output_Feature_Class = "C:\\Users\\" + a + "\\Documents\\ArcGIS\\Default.gdb\\Bnd_"
If you work on Windows (and this will work for Windows only) the pywin module can find the path to documents:
from win32com.shell import shell, shellcon
a = shell.SHGetFolderPath(0, shellcon.CSIDL_PERSONAL, None, 0)
Output_Feature_Class = "{}\\ArcGIS\\Default.gdb\\Bnd_".format(a)
but this is not cross platform. Thanks to martineau for this solution see Finding the user's "My Documents" path for finding Documents path.
Instead of storing temporary files in a location of your choosing which may or may not exist, why not use the Windows %TEMP% environment variable? If they don't have %TEMP% set, a lot of software wont work.
import os
def set_temp_path(*args):
if os.name is 'nt':
temp_path = os.getenv('TEMP')
if not temp_path:
raise OSError('No %TEMP% variable is set? wow!')
script_path = os.path.join(temp_path, *args)
if not os.path.exists(script_path):
os.makedirs(script_path)
return script_path
elif os.name is 'posix':
#perform similar operation for linux or other operating systems if desired
return "linuxpath!"
else:
raise OSError('%s is not a supported platform, sorry!' % os.name)
You can use this code for arbitrary temporary file structures for this or any other script:
my_temp_path = set_temp_path('ArcGIS', 'Default.gdb', 'Bnd_')
Which will create all the needed directories for you and return the path for further use in your script.
'C:\\Users\\JSmith\\AppData\\Local\\Temp\\ArcGIS\\Default.gdb\\Bnd_'
This is of course incomplete if you intend on supporting multiple platforms, but this should be straightforward on linux using the global /tmp or /var/temp paths.
To get the user's home directory you can use os.path.expanduser to get a user's home directory.
Output_Feature_Class = os.path.join(os.path.expanduser('~'), "Documents\\ArcGIS\\Default.gdb\\Bnd_")
As mentioned by others, before you do this please consider if this is the best location for these files. Temporary files should be in a location reserved by OS conventions for temporary files.
please help convert the variable "fileNameClean" so that you can open the file via the module "shelve"
import shelve
fileName = 'C:/Python33/projects/DVD_LIST/p3_dvd_list_shelve_3d_class_edit_menubar/data.dir'
print('___', fileName)
str = fileName.split('/')[-1]
print('--', str)
fileNameClean = str.split('.')[0:-1]
print(fileNameClean) #['data']
db = shelve.open(fileNameClean) #open error
Use the os.path module to produce a clean path:
import os.path
fileName = 'C:/Python33/projects/DVD_LIST/p3_dvd_list_shelve_3d_class_edit_menubar/data.dir'
fileNameClean = os.path.splitext(os.path.basename(fileName))[0]
db = shelve.open(fileNameClean)
Your code also produced a base name minus the extension, but you returned a list by using a slice (from index 0 until but not including the last element). You could have used fileNameClean[0], but using the os.path module makes sure you catch edgecases in path handling too.
You probably want to make sure you don't use a relative path here either. To open the shelve file in the same directory as the current script or module, use __file__ to get an absolute path to the parent directory:
here = os.path.dirname(os.path.abspath(__file__))
db = shelve.open(os.path.join(here, fileNameClean))
How do I get the current file's directory path?
I tried:
>>> os.path.abspath(__file__)
'C:\\python27\\test.py'
But I want:
'C:\\python27\\'
The special variable __file__ contains the path to the current file. From that we can get the directory using either pathlib or the os.path module.
Python 3
For the directory of the script being run:
import pathlib
pathlib.Path(__file__).parent.resolve()
For the current working directory:
import pathlib
pathlib.Path().resolve()
Python 2 and 3
For the directory of the script being run:
import os
os.path.dirname(os.path.abspath(__file__))
If you mean the current working directory:
import os
os.path.abspath(os.getcwd())
Note that before and after file is two underscores, not just one.
Also note that if you are running interactively or have loaded code from something other than a file (eg: a database or online resource), __file__ may not be set since there is no notion of "current file". The above answer assumes the most common scenario of running a python script that is in a file.
References
pathlib in the python documentation.
os.path - Python 2.7, os.path - Python 3
os.getcwd - Python 2.7, os.getcwd - Python 3
what does the __file__ variable mean/do?
Using Path from pathlib is the recommended way since Python 3:
from pathlib import Path
print("File Path:", Path(__file__).absolute())
print("Directory Path:", Path().absolute()) # Directory of current working directory, not __file__
Note: If using Jupyter Notebook, __file__ doesn't return expected value, so Path().absolute() has to be used.
In Python 3.x I do:
from pathlib import Path
path = Path(__file__).parent.absolute()
Explanation:
Path(__file__) is the path to the current file.
.parent gives you the directory the file is in.
.absolute() gives you the full absolute path to it.
Using pathlib is the modern way to work with paths. If you need it as a string later for some reason, just do str(path).
Try this:
import os
dir_path = os.path.dirname(os.path.realpath(__file__))
import os
print(os.path.dirname(__file__))
I found the following commands return the full path of the parent directory of a Python 3 script.
Python 3 Script:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from pathlib import Path
#Get the absolute path of a Python3.6 and above script.
dir1 = Path().resolve() #Make the path absolute, resolving any symlinks.
dir2 = Path().absolute() #See #RonKalian answer
dir3 = Path(__file__).parent.absolute() #See #Arminius answer
dir4 = Path(__file__).parent
print(f'dir1={dir1}\ndir2={dir2}\ndir3={dir3}\ndir4={dir4}')
REMARKS !!!!
dir1 and dir2 works only when running a script located in the current working directory, but will break in any other case.
Given that Path(__file__).is_absolute() is True, the use of the .absolute() method in dir3 appears redundant.
The shortest command that works is dir4.
Explanation links: .resolve(), .absolute(), Path(file).parent().absolute()
USEFUL PATH PROPERTIES IN PYTHON:
from pathlib import Path
#Returns the path of the current directory
mypath = Path().absolute()
print('Absolute path : {}'.format(mypath))
#if you want to go to any other file inside the subdirectories of the directory path got from above method
filePath = mypath/'data'/'fuel_econ.csv'
print('File path : {}'.format(filePath))
#To check if file present in that directory or Not
isfileExist = filePath.exists()
print('isfileExist : {}'.format(isfileExist))
#To check if the path is a directory or a File
isadirectory = filePath.is_dir()
print('isadirectory : {}'.format(isadirectory))
#To get the extension of the file
fileExtension = mypath/'data'/'fuel_econ.csv'
print('File extension : {}'.format(filePath.suffix))
OUTPUT:
ABSOLUTE PATH IS THE PATH WHERE YOUR PYTHON FILE IS PLACED
Absolute path : D:\Study\Machine Learning\Jupitor Notebook\JupytorNotebookTest2\Udacity_Scripts\Matplotlib and seaborn Part2
File path : D:\Study\Machine Learning\Jupitor Notebook\JupytorNotebookTest2\Udacity_Scripts\Matplotlib and seaborn Part2\data\fuel_econ.csv
isfileExist : True
isadirectory : False
File extension : .csv
works also if __file__ is not available (jupyter notebooks)
import sys
from pathlib import Path
path_file = Path(sys.path[0])
print(path_file)
Also uses pathlib, which is the object oriented way of handling paths in python 3.
IPython has a magic command %pwd to get the present working directory. It can be used in following way:
from IPython.terminal.embed import InteractiveShellEmbed
ip_shell = InteractiveShellEmbed()
present_working_directory = ip_shell.magic("%pwd")
On IPython Jupyter Notebook %pwd can be used directly as following:
present_working_directory = %pwd
I have made a function to use when running python under IIS in CGI in order to get the current folder:
import os
def getLocalFolder():
path=str(os.path.dirname(os.path.abspath(__file__))).split(os.sep)
return path[len(path)-1]
Python 2 and 3
You can simply also do:
from os import sep
print(__file__.rsplit(sep, 1)[0] + sep)
Which outputs something like:
C:\my_folder\sub_folder\
This can be done without a module.
def get_path():
return (__file__.replace(f"<your script name>.py", ""))
print(get_path())