Today I’m going to talk about a special builtin variable __file__
as it is implemented in the RevitPythonShell. This feature is only available to external scripts
and RpsAddins. This is similar to how __file__
is normally defined for Python: It is not defined in the REPL.
Simply put: __file__
contains the path to the current file being run.
With external scripts, this is a path to a python script. With RpsAddins, it is the path to the addin’s DLL, a path separator, and the name of the script (e.g. C:\Program Files (x86)\MyAddin\MyAddin.dll\helloworld.py
).
Suppose you have deployed some scripts to another computer. Suppose those scripts rely on other files - a database, maybe, or icons, pictures, anything really. If you keep referencing these files as C:\Users\Gareth\AwesomeScripts\all_my_data.sqlite
you are going to run into difficulties on a computer that doesn’t belong to Gareth. Meg’s computer won’t know how to find the database! And she is going to complain to Meg and meg is going to complain to her boss and her boss is going to complain to your boss and your boss is going to go get coffee, lock himself up in his office and brood for a very long time. Then, he’s going to send someone to tell you to come to his office ASAP. Now!
You don’t want that to happen! That is why you’re going to make sure that all file references are relative to the installation of your external scripts / RpsAddins. And unless you have a priori knowledge of the folder name you’re installing to, well, I’ve got your back:
def get_folder():
import os
# assume external script
folder = os.path.dirname(__file__)
if folder.lower().endswith('.dll'):
# nope - RpsAddin
folder = os.path.dirname(folder)
return folder
Hello Daren,
ReplyDeleteI tried to use this in one of my script without success. What I did wrong ?
#script start
import os
import wpf
def get_folder():
# assume external script
folder = os.path.dirname(__file__)
if folder.lower().endswith('.dll'):
# nope - RpsAddin
folder = os.path.dirname(folder)
return folder
class MyWindow(Window):
def __init__(self):
folder = get_folder()
gui_path = os.path.join(folder, 'outils_revit.xaml')
wpf.LoadComponent(self, gui_path)
Then I tried something simpler to display this path but I only got empty strings :
def get_folder():
# assume external script
folder = os.path.dirname(__file__)
if folder.lower().endswith('.dll'):
# nope - RpsAddin
folder = os.path.dirname(folder)
return folder
TaskDialog.Show('Test', get_folder())
TaskDialog.Show('Test', os.path.dirname(__file__))
Any idea ?
P.S. Your book "Scripting Autodesk Revit with RevitPythonShell" helped me a lot in creating a full installer. Thanks.
did you type this into the interactive shell? (`__file__` is empty for the interactive shell...)
Deletedid you try to do `TaskDialog.Show('Test', __file__)`? This is the most simple test - or even: `print __file__`...
No, I typed this in external scripts.
DeleteI tried `TaskDialog.Show('Test', __file__)` it return a empty dialog. I tried `print __file__`, it returns nothing.
is your version of RPS current? i've just tried it again in RPS 2016... and in RPS 2014... and in RPS 2015 - using a simple external script ("print __file__")
DeleteSorry for late answer, irl issues. I installed RPS on Revit 2016 and it worked... I don't understand... Thanks
Delete