Defining new classes from macro or script

Need help, or want to share a macro? Post here!
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
Post Reply
acikgozbc
Posts: 6
Joined: Tue Sep 21, 2021 8:59 am

Defining new classes from macro or script

Post by acikgozbc »

Hello everyone. I have a .py module that I have written on my own with some class definitions. This module is located at the freecad/bin and I can import it from FreeCAD Python console. However, I cannot create new instances of the defined classes from a macro. Is there a way to do it from a macro?

As an example, here is my .py module:

def someClass:
def __init___(self,name):
self.name = name

And in the macro

someInstance = someClass("instance name")

I encounter "someClass is not defined" error.
TheMarkster
Veteran
Posts: 5513
Joined: Thu Apr 05, 2018 1:53 am

Re: Defining new classes from macro or script

Post by TheMarkster »

I never put .py files in the bin folder because I keep FreeCAD in drive e: (my SSD drive c: where Windows is installed is cramped for space). I download the .7z build, extract to drive e: and then delete the old folder. So it wouldn't be good for me to have files in that folder I wanted to keep. If the .py file is to be used in a macro I put it in the macros folder. But here is a way I found that worked for putting them in the bin folder.

I have FreeCAD installed in the FREECADPATH folder. In the bin folder is a file named test.py:

Code: Select all

class Test:
    def __init__(self):
        pass

    def getString(self):
        return "howdy!"
In my macros folder, test.FCMacro:

Code: Select all

FREECADPATH= 'e:/FreeCAD_0.20.25645_Win-LPv12.5.4_vc17.x-x86-64/bin'
import sys
sys.path.append(FREECADPATH)
import FreeCAD as App, FreeCADGui as Gui
import test

t = test.Test()
print(t.getString())
acikgozbc
Posts: 6
Joined: Tue Sep 21, 2021 8:59 am

Re: Defining new classes from macro or script

Post by acikgozbc »

TheMarkster wrote: Tue Sep 21, 2021 3:39 pm I never put .py files in the bin folder because I keep FreeCAD in drive e: (my SSD drive c: where Windows is installed is cramped for space). I download the .7z build, extract to drive e: and then delete the old folder. So it wouldn't be good for me to have files in that folder I wanted to keep. If the .py file is to be used in a macro I put it in the macros folder. But here is a way I found that worked for putting them in the bin folder.

I have FreeCAD installed in the FREECADPATH folder. In the bin folder is a file named test.py:

Code: Select all

class Test:
    def __init__(self):
        pass

    def getString(self):
        return "howdy!"
In my macros folder, test.FCMacro:

Code: Select all

FREECADPATH= 'e:/FreeCAD_0.20.25645_Win-LPv12.5.4_vc17.x-x86-64/bin'
import sys
sys.path.append(FREECADPATH)
import FreeCAD as App, FreeCADGui as Gui
import test

t = test.Test()
print(t.getString())
I actually couldn't get your suggestion to work. On the other hand, what I did was as follows:
Let us assume I have my .py script (let us assume that it is named as myScript) located at some path "C:/Users/username/Desktop", then I defined a macro as:

FreeCADGui.doCommand('path = "C:/Users/username/Desktop"')
FreeCADGui.doCommand('sys.path.insert(0,path)')
FreeCADGui.doCommand('from myScript import *')

Now all the class definitions are imported :)
TheMarkster
Veteran
Posts: 5513
Joined: Thu Apr 05, 2018 1:53 am

Re: Defining new classes from macro or script

Post by TheMarkster »

acikgozbc wrote: Mon Sep 27, 2021 2:05 pm
I actually couldn't get your suggestion to work. On the other hand, what I did was as follows:
Let us assume I have my .py script (let us assume that it is named as myScript) located at some path "C:/Users/username/Desktop", then I defined a macro as:

FreeCADGui.doCommand('path = "C:/Users/username/Desktop"')
FreeCADGui.doCommand('sys.path.insert(0,path)')
FreeCADGui.doCommand('from myScript import *')

Now all the class definitions are imported :)
Very clever.

But now if you now enter:

Code: Select all

path
in the python console it returns the string you defined in the script. This is polluting the namespace, so to speak. You can avoid this in a couple ways. One way, if possible, is to avoid creating the variable at all. You can combine your first 2 lines into a single line without need of defining the variable. In cases where a temporary variable is needed I believe there is a convention to use the underscores for temporary variables and then to delete the temp variable afterwards with del:

Code: Select all

del _path_
acikgozbc
Posts: 6
Joined: Tue Sep 21, 2021 8:59 am

Re: Defining new classes from macro or script

Post by acikgozbc »

TheMarkster wrote: Mon Sep 27, 2021 4:34 pm
acikgozbc wrote: Mon Sep 27, 2021 2:05 pm
I actually couldn't get your suggestion to work. On the other hand, what I did was as follows:
Let us assume I have my .py script (let us assume that it is named as myScript) located at some path "C:/Users/username/Desktop", then I defined a macro as:

FreeCADGui.doCommand('path = "C:/Users/username/Desktop"')
FreeCADGui.doCommand('sys.path.insert(0,path)')
FreeCADGui.doCommand('from myScript import *')

Now all the class definitions are imported :)
Very clever.

But now if you now enter:

Code: Select all

path
in the python console it returns the string you defined in the script. This is polluting the namespace, so to speak. You can avoid this in a couple ways. One way, if possible, is to avoid creating the variable at all. You can combine your first 2 lines into a single line without need of defining the variable. In cases where a temporary variable is needed I believe there is a convention to use the underscores for temporary variables and then to delete the temp variable afterwards with del:

Code: Select all

del _path_
This advice is indeed golden. For now, I am not experiencing many polluted namespace problems since it is still a small package but I believe in the near future I might experience the drawbacks of reckless namespace usage. Therefore, thank you very much for your comment.
Post Reply