21 comments

[ 0.66 ms ] story [ 65.0 ms ] thread
(comment deleted)
Is there any language that makes breaking out code into separate files as simple as maybe just importing a file. c and cpp i guess with quote includes, even that is annoying with header files and linking args when compiling.
golang is pretty good for this. you can stick a bunch of files together and just mark them as being in the same package and all their functions will get wadded together in the resultant package for other stuff to import.
Package visibility is actually one of the things I dislike the most about golang :(

Coming from Python, I got used to the "explicit is better than implicit" Zen. With "import *" being discouraged, usually when you see something in your Python code, you know exactly where it came from. When I started out with golang, seeing references to things that came out of nowhere (to my eyes) annoyed the hell out of me. I still consider this a cognitive burden.

I'm not sure I understand.

Generally in Go: functions, structs, and consts are namespaced in a way I think is familiar to most, by package origin.

If something is not, then it's either a function/struct in the same namespace (same file, or directory), variable in same scope, or it's a built-in.

Built-ins like `append`, are not much different than say `map`, `filter`, `max`, etc in Python.

Anything sourced from a subdirectory, parent directory, or sibling directory needs to be explicitly imported via the module path.

I discovered how it works by fighting with the compiler far longer than I will admit trying to force it to import the other files in the directory :)
Yeah that is counter intuitive till you forget not knowing it.
Yes, Ruby. But there's tradeoffs and frankly Python's file name = namespace name approach makes finding things much easier when you don't know where they've been imported from.

In Ruby people achieve something similar by convention (explicitly creating a namespace and keeping the names in sync with the file name), but not everyone follows convention and things can turn into a mess.

If I had to suggest one flaw in Ruby it would be this, in many other ways I find it nicer to code in then Python, but honestly this one thing is enough to really sour the experience.

The ability to open and modify any class at any time really prevents filenames from being the namespace. It is both a powerful feature and a hindrance to code discoverability.

Discoverability in Ruby is usually done via IRB, and you can call "source_location" on a method to find where in code it the method is defined (or redefined, as can happen in Ruby)

For all the things wrong with node, I envy the relative filename importing they have when writing Python.
when I moved from Python to NodeJS years ago the way that `require( './path/to/file.js' );` works was a total revelation. There are still arguments being mafe about NodeJS's `require` rules being too complicated (e.g. using optionally implicit extensions) but even with that, NodeJS's `require()` method is hands down superior to Python's `import` statement.
From the HN Guidelines:

> Otherwise please use the original title, unless it is misleading or linkbait; don't editorialize.

As a hobbyist Python programmer (that only really ever used it in grad school) this was an extreme pain point when it came to using a much smaller library when getting started with Home Assistant.

PyScript seems to take away the pain of using YAML and all the boilerplate created to make it so people in the system don't have to program. But there is just so much you have to know about the quirks of the language on top of the quirks of the author's specific choices.

if you don't care about doing things right and packing crap into a shared virtual environment and all that, you can just create a directory called "deps". fill it with symlinks to directories you want to import or import from. they'll import just fine. probably should have been how it works the entire time.
This is a cleaner solution than anything presented in the answers.
Agreed - why isn’t this a recommended solution?
(Can we avoid the editorialized titles?)

Relative imports and mucking with sys.path should be avoided. This StackOverflow answer is providing the right recommendation: make your code into a library. You can do this via pyproject.toml or setup.py, and it's really quite painless. The sooner you do so, the easier things will be.

If you really just want to hack something together (and aren't planning on sharing the code with anyone), you can use importlib to import a Python source file directly [0].

0: https://docs.python.org/3/library/importlib.html#importing-a...

I've been organizing my python projects starting with package folders.

Say I name my package "foo", foo is the top level folder for the source code. Inside foo there is a "main.py" file as the project's start point, and other various modules, let's have one called "module1.py". Now, add another package under "foo", the obvious example name here would be "bar", and add another module under "bar" called "module2.py".

The project structure looks like this:

  - foo/
    |- main.py
    |- module1.py
    |- bar/
       |- module2.py
To reference "module1.py" in "module2.py", just write

  import foo.module1
To reference "module2.py" in "main.py", do as follows

  import foo.bar.module2

There is no problem importing from any level.

To start the program from command line, enter:

python -m foo.main

anecdotally I can support that `python -m x.py` is a better way to go than `python x.py`. Somewhere I found the tip that writing `python3.9 -m pip install $pkg` is a more reliable way to run `pip` for a specific version.

It should not be so complicated.