[Python] how to call a def in another class that in turn calls a def of the caller class

Here's the place for discussion related to coding in FreeCAD, C++ or Python. Design, interfaces and structures.
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
User avatar
chennes
Veteran
Posts: 3876
Joined: Fri Dec 23, 2016 3:38 pm
Location: Norman, OK, USA
Contact:

Re: [Python] how to call a def in another class that in turn calls a def of the caller class

Post by chennes »

I'll give the code a look in a minute...

Side note: it appears you are making a public function that you prefix with an underscore. In Python we do not do that, the underscore is used to indicate that a function is "private", that is, that your IDE should not list it as a possible completion for outside code to call. It's just a convention, of course, Python itself doesn't have the idea of private functions. Nevertheless, it appears from the code blocks in this discussion that you should lose the underscore in the method name.
Chris Hennes
Pioneer Library System
GitHub profile, LinkedIn profile, chrishennes.com
User avatar
chennes
Veteran
Posts: 3876
Joined: Fri Dec 23, 2016 3:38 pm
Location: Norman, OK, USA
Contact:

Re: [Python] how to call a def in another class that in turn calls a def of the caller class

Post by chennes »

Two things jump out at me: first, you do not need to import writer -- since you are passing it into the class, there is no need for the line that also imports its definition. Python doesn't care -- as long as the writer object provides the needed functions at call-time, you are good to go.

Second, you appear to be referencing a non-existent object (write):

Code: Select all

def _getElectrostaticSolver(self, equation):
        # check if we need to update the equation
        self._updateElectrostaticSolver(equation)
        # output the equation parameters
        s = self.write._createLinearSolver(equation)
As far as I can see, there is no "self.write" -- maybe you mean "self.writer"?
Chris Hennes
Pioneer Library System
GitHub profile, LinkedIn profile, chrishennes.com
User avatar
uwestoehr
Veteran
Posts: 4961
Joined: Sun Jan 27, 2019 3:21 am
Location: Germany
Contact:

Re: [Python] how to call a def in another class that in turn calls a def of the caller class

Post by uwestoehr »

chennes wrote: Sun Feb 05, 2023 4:22 pm Two things jump out at me: first, you do not need to import writer
Second, you appear to be referencing a non-existent object (write):... As far as I can see, there is no "self.write" -- maybe you mean "self.writer"?
Many thanks! I fixed this and now it works.

I made a PR to make the first step to refactor the writer.py beast:
https://github.com/FreeCAD/FreeCAD/pull/8362
I hereby also followed the naming convention that defs now addressed by another class, don't get the underscore. I hope I did it right.
agren
Posts: 40
Joined: Sat Apr 20, 2019 7:37 am

Re: [Python] how to call a def in another class that in turn calls a def of the caller class

Post by agren »

Edit: Saw, after I posted, that you got it to work so you can ignore this post.

@uwestoehr
The stack trace cannot look like this:

Code: Select all

05:59:31    File "D:\FreeCAD-build\Mod\Fem\femsolver\elmer\writer.py", line 857, in _handleElectrostatic
05:59:31      ESW = ES_writer.ESwriter(self, self.solver)
05:59:31    File "D:\FreeCAD-build\Mod\Fem\femsolver\elmer\equations\electrostatic_writer.py", line 41, in __init__
05:59:31      self.write = writer.Writer(self.solver, self.directory)
If ESwriter only have one definition of __init__, that looks like the following, in electrostatic_writer.py:

Code: Select all

class ESwriter:

    def __init__(self, writer, solver):
        self.writer = writer
        self.solver = solver


According to the stack trace ESwriter.__init__ in D:\FreeCAD-build\Mod\Fem\femsolver\elmer\equations\electrostatic_writer.py, line 41, looks like this:

Code: Select all

self.write = writer.Writer(self.solver, self.directory)
openBrain
Veteran
Posts: 9034
Joined: Fri Nov 09, 2018 5:38 pm
Contact:

Re: [Python] how to call a def in another class that in turn calls a def of the caller class

Post by openBrain »

uwestoehr wrote: Thu Feb 02, 2023 1:03 am How can I sort out code from a class to another file?

For example I have a large class called "Writer". it has dozens of defs and they call each other. I want to move some defs to another .py file to keep the overview.

My attempt was to take some def from class "Writer" to a new file, put them there into a class called e.g. "ESwriter".
The point is that the defs in calss ESwriter in turn calls some other defs in class Writer. This compiles but when executed the other defs in calss Writer do not return anything.
Have this open for a long time.
In case it may be useful again, I guess you could use dynamic subclassing in Python. Here is a very simple example to demonstrate :

Code: Select all

class Writer:

	def __init__(self, es=False):
		self.testme()
		App.Console.PrintMessage("Testing if needs dynamic subclassing\n")
		if es:
			self.__class__ = ESWriter
			self.specificInit()
		self.testme()
		App.Console.PrintMessage("---------------\n")

	def testme(self):
		App.Console.PrintMessage("I'm a Writer\n")

class ESWriter(Writer):

	def __init__(self):
		super.__init__()
		specificInit()

	def specificInit(self):
		# do specific init actions here
		pass

	def testme(self):
		App.Console.PrintMessage("I'm a ESWriter\n")

Writer()

Writer(True)
User avatar
uwestoehr
Veteran
Posts: 4961
Joined: Sun Jan 27, 2019 3:21 am
Location: Germany
Contact:

Re: [Python] how to call a def in another class that in turn calls a def of the caller class

Post by uwestoehr »

openBrain wrote: Wed Feb 08, 2023 3:48 pm In case it may be useful again, I guess you could use dynamic subclassing in Python. Here is a very simple example to demonstrate :
Many thanks!

However, in the meantime I was able to refactor the file, thanks to the help of @agren and @chennes. This was the first step:
https://github.com/FreeCAD/FreeCAD/pull ... f5acb6fe7a
then I refactored is step by step the same way.
Post Reply