Describe python "project" structure

Sure, so don’t go learn about metaclasses. But you do need to learn the basics - and (for better or worse) importing modules is a basic and necessary part of working with multi file projects.

Graphical applications are always complicated and I don’t understand how you expect to successfully extend one without learning how the import and package systems work. This is not unique to Python - It would be like trying to add to a C++ project without knowing what #include does or how object linking works. And the easiest way to get to grips with it is to write a smaller sample project - two files! And play with it. Any time something in the bigger project doesn’t make sense, you can try to minimally reproduce it in the toy project. This works as a problem solving method because it removes all the unrelated variables.

Version control, my friend. :wink:

1 Like

I believe the last two replies just opened a “bag of worms” for me.

After the last posts , It is no longer a simple( C ) “file” - it is script , function , module , package… then the most confusing "import " . I really need to read a "Python for dummies " booK.

Perhaps. Though it may not address what you’re after.

I was ready to add a new class to the code and now I have no clue HOW and where

  • as a package , module , script , function ?? Perhaps PyCharm will
    guide me …

My rule of thumb is: add the code in a file with similar code.

The other parts of the app/programme which want your code will have to
import it from wherever it lives anyway. Hopefully there’s a sensible
looking module/package which already contains code similar to what you
want to add, in terms of what it works on.

Put it there.

Whatever uses it will be going:

 from the.suitable.package import your_function

anyway, so the real objective is simply to choose an apt
the.suitable.package. Sometimes the package exists but all the files
in the package are just off from what you’re doing. As an example,
here’s the contents of a foo.util package I’m working with:

 __init__.py
 debug.py
 dirtree.py
 fs.py
 html.py
 lex.py
 metadata.py
 models.py
 orm.py
 testing.py
 tests/

Being util, it’s for ad hoc utility things that support other parts of
the app: there’re modules in there for:

  • debug.py: some debugging functions
  • fs.py: function do do with the filesystem, like file pathnames and making directories in a particular way etc
  • html.py: function to generate common HTML snippets
  • lex.py: lexical parsing things
  • orm.py: common tasks we do using the ORM (db interface)

If I need to add a new “utility” function it will go in here somewhere.
If the utility is not nicely in one of the categories each file above
represents, I’ll make a new file for it sutiably named.

Supposing I needed to add some statistical thing. I might make a new statistics.py
file and put it in there. The code using my new function stat_func would go:

 from foo.util.statisics import stat_func

and just get on with it.

Cheers,
Cameron Simpson cs@cskk.id.au

Nice, but still somewhat confusing.

I firmly believe that to be a successful coder, and I am deliberately not using “software engineer” , one has to adapt to the language terminology and try to consistently use it.

After coming from C it looks as if python is not a code , but a script… Do not get me wrong - I am not pushing terminology just to be an ass , but without it - starting any language is a mess.

So I still have module = package = folder. ( And PyCharm "added .py file " …)

I just successfully implemented a debug function , now I am trying to add it to a “module = folder = package…” - using “from … import”…
Not finished yet - cannot really find why I cannot implement it in another “module”, but working on it.

So I ended up with this

test import

from src.NanoVNASaver.Windows.AA7EJ_ADDS.Debug_Module import introduction
exit(42)

therefore a question

do I have to copy the “full path” (src.NanoVNASaver.Windows.AA7EJ_ADDS.Debug_Module) or is there a way I can "define it " as a constant ?

Nice, but still somewhat confusing.

Well, it’s an example. All projects have slightly (or sometimes very)
different layouts and conventions. But loosely speaking: put your new
code in with other code of the same or similar purpose, wherever that
place turns out to be.

I firmly believe that to be a successful coder, and I am deliberately not using “software engineer” , one has to adapt to the language terminology and try to consistently use it.

After coming from C it looks as if python is not a code , but a script… Do not get me wrong - I am not pushing terminology just to be an ass , but without it - starting any language is a mess.

The distinction’s somewhat arbitrary. But Python is a
run-it-when-imported language. C and other static languages have a
distinct “compile and link” step. There are parallels in Python, but in
terms of feel that’s perhaps what you’re seeing. Of coure there are
other differences as well.

So I still have module = package = folder. ( And PyCharm "added .py file " …)

Ok, not quite.

Any Python .py file is a module. A file foo.py can be imported as
the module foo (maybe with a prefix depending on where in the source
tree it is).

A package is a directory with multiple .py files inside it. If you’ve
got a directory named foo with:

 __init__.py
 bah.py

Then you can import foo, and it imports the foo/__init__.py file. Or
import foo.bah and it imports the foo.bah.py file. So __init__.py
is a kind of “default” module to load if you ask for just foo. Its
purpose is to initialise that package (if that’s necessary at all; this
can be an empty file and these days is even optional).

So I ended up with this

test import

from src.NanoVNASaver.Windows.AA7EJ_ADDS.Debug_Module import introduction
exit(42)

therefore a question

do I have to copy the “full path”
(src.NanoVNASaver.Windows.AA7EJ_ADDS.Debug_Module) or is there a way I
can "define it " as a constant ?

It looks to me like this Python project keeps all its Python code in a
src/ subdirectory. This is very common.

Normally the environment you’re working in will have that src
subdirectory in the $PYTHONPATH, so that it is one of the normal
places to look in for imports. With that setting your import would be:

 import NanoVNASaver.Windows.AA7EJ_ADDS.Debug_Module

Usually you’d have some kind of environment file to source which would
arrange that for you (the $PYTHONPATH)while you’re working there.

Cheers,
Cameron Simpson cs@cskk.id.au

OK, I think I have a basic understanding of “import”.
Now for the real question, pretty stupid but I have not found an
example “how to actually use imported function”…

Here is my partial script

test import function introduction

from src.NanoVNASaver.Windows.AA7EJ_ADDS.Debug_Module import introduction
#run function
introduction(“TEST”)
exit(42)

and here is function definition inf the "Debug_Modke

def introduction(name):
“”“Introduces a person given their name”“”
print(‘Hello! My name is’, name)
introduction(“Kateryna”)

it executes introduction(“Kateryna”) when run in the module itself

and I get this output when running the entire application

/usr/bin/python3.10 /mnt/RAID_124/TEST_CLONE (copy)/nanovna-saver.py
Traceback (most recent call last):
File “/mnt/RAID_124/TEST_CLONE (copy)/nanovna-saver.py”, line 22, in
from src.NanoVNASaver.Windows.AA7EJ_ADDS.Debug_Module import introduction
File “/mnt/RAID_124/TEST_CLONE
(copy)/src/NanoVNASaver/Windows/init.py”, line 1, in
from .About import AboutWindow
File “/mnt/RAID_124/TEST_CLONE
(copy)/src/NanoVNASaver/Windows/About.py”, line 28, in
from NanoVNASaver.Windows.Defaults import make_scrollable
ModuleNotFoundError: No module named ‘NanoVNASaver.Windows.Defaults’

Process finished with exit code 1

Obviously my attempt to run function “introduction” from the parent
module is wrong.
Would appreciate assistance / solution on how to fix this or
reference to " how to execute imported function " .
Thanks

On Mon, Jul 10, 2023 at 3:13 AM Cameron Simpson via Discussions on

Your import is ok, but the imports in the modules you’re importing fail.

Notice this line:

 from NanoVNASaver.Windows.Defaults import make_scrollable

This says that it expected to be able to import from NanoVNASaver,
whereas you’re expecting src.NanoVNASaver. The latter is because you
haven’t added the src subdirectory to $PYTHONPATH.

Try:

 export PYTHONPATH=$PWD/src:$PYTHONPATH

then try your code again, after removing the src. from your own
import (it should no longer be necessary).

Cheers,
Cameron Simpson cs@cskk.id.au

Thanks for the replay.

I definitely have TWO issues

  1. I need to keep better track which file / script is the “main” executable -

I have "nanoVNASaver " and " nanoVNA_saver "

  1. Then I need to figure out “from …include” hierarchy / dependency.
    I did build my “Debug_module.py” and it seems to need dome “parent” modules when integrated with the existing code. Not sure why - it works as expected when running “solo”.

I hope I can use PyCharm to help me with this task.

Let me fix these and then I’ll get back to you if I need to add the path you have suggested.

Thanks