4 ms·
What problem are you having with imports? Believe I had a few issues in the Py2 times, but things improved and haven't in years.
by mixmastamyk 4y ago
What problem are you having with imports? Believe I had a few issues in the Py2 times, but things improved and haven't in years.
- DemocracyFTW2 4y ago> > The entire import system is broken > What problem are you having with imports? This is a Python function I wrote some years ago to import a module when given a path: def module_from_path( name, path ): ### thx to https://stackoverflow.com/a/50395128/7568091 ### ### thx to https://stackoverflow.com/a/67692/7568091 ### import importlib import importlib.util spec = importlib.util.spec_from_file_location( name, path ) module = importlib.util.module_from_spec( spec ) sys.modules[ spec.name ] = module spec.loader.exec_module( module ) return importlib.import_module( name ) There are so many conspicuous things about it but to put it short, I should be able to just give a relative or absolute file path, call one method, and be done. Damn all those intermediate steps, and why do I have to name it?
- IshKebab 4y agoNice idea, unfortunately it will break all static tooling. IDEs, static type checker, linters, etc. I used to work at a company where they had a custom import system and it was a nightmare.
- mixmastamyk 4y agoWe use it to load classes from the command-line in a pretty big project. That part works perfectly.
- mixmastamyk 4y agoIt is easier in Python 3 than it was. I wrote this and it worked on the first try, although I have some experience with it. The dynamic module: » cat sub/test_module.py def hello(name): print(f'Hello {name}') The main script: » cat test_script.py from importlib import import_module full_module_path = 'sub.test_module' # no ".py" module = import_module(full_module_path) # optional, if you want to use across the project: import sys sys.modules[full_module_path] = module print(sys.modules[full_module_path]) # end optional # try it: module.hello('there!') To run it: » python3 test_script.py <module 'sub.test_module' from '/home/foo/sub/test_module.py'> Hello there! Stack overflow has its uses. But you shouldn't rely on it if things have changed, a lot of their advice is outdated and written by non-experts. The importlib module docs explain this concisely. https://docs.python.org/3/library/importlib.html#importlib.import_module https://docs.python.org/3/library/importlib.html#importlib.i... In general, I don't see the intrinsic complexity being reduced much more than this: from importlib import import_module module = import_module('sub.test_module')
- DemocracyFTW2 4y agoYeah this was years ago so if that has improved since good for the Python people. > In general, I don't see the intrinsic complexity being reduced much more than this you know in NodeJS I do `const tm = require('sub/test_module');` which I for a number of reasons do find inherently less complex.
- mixmastamyk 4y agoIt's not a builtin in Python-land because importing from a string is exceedingly rare there. I prefer to skip quotes and parens for the 99% case.
- IshKebab 4y agoThis question should give you an idea of some of the issues: https://stackoverflow.com/questions/14132789/relative-imports-for-the-billionth-time https://stackoverflow.com/questions/14132789/relative-import...
- mixmastamyk 4y agoLooks like people thought "." refers to the filesystem CWD instead of the current package. Python never made shell constructs that central. Admittedly, it never occurred to me to confuse these two, and so haven't had any of the problems any of those folks mention. And you need (maybe used to?) an __init__.py file in each package. But once you know that, it's straightforward, no? Certainly not, "only a few people in the world know this..." level. Don't think I'm some kinda level-10 genius here.
- IshKebab 4y ago> Looks like people thought "." refers to the filesystem CWD instead of the current package. Yes because referring to the filesystem is logical and intuitive and referring to some abstract "package" that changes depending on how you invoke Python is insane. > But once you know that, it's straightforward, no? I wish!
- mixmastamyk 4y agoIt's a programming language, not a shell, of course. It has always been strict about syntax as well. I don't expect "&" or ">" to work the same in the shell as I do in Python—why would I expect "." to? Close to none of the notation of Python works the same as a shell. Even quotes, which are superficially similar but have significant differences. > abstract "package" Packages are not abstract, they are simply a folder with .py files inside. Sounds concrete enough to me. > changes depending on how you invoke Python I'm not sure what this refers to? I know you can change PYTHONPATH. And the current folder portion changes with it.
- EdwardDiego 4y agoMy one massive hate about Python imports, path resolution aside, is that if I want to do from foo.bar import Baz And there's a foo/__init__.py file it gets executed merely from path traversal. And because of how Django's settings work (import django.settings and all your stuff is magically there), people in my company have gotten into the habit of putting code in settings/__init__.py to do the things they need, like retrieve secrets from AWS. Which I don't want to have happen when I'm trying to import settings.bla_module to use a type in a unit test.
- mixmastamyk 4y ago> And there's a foo/__init__.py file it gets executed merely from path traversal. Yes, and it needs to—to find the variables there, which may/not be other packages. > how Django's settings work Right. Django is great and popular, and so I think many folks don't realize how downright clunky it is in a number of places. Many parts of it are over-engineered like this one. It has improved over time but some things are set in stone due to history. I'd like their settings redesigned myself. > __init__.py to do the things they need, like retrieve secrets from AWS No, no, no, no... NO! ;-) Imports should only create variables, define functions, and/or alias a package. They should never, ever run lengthy computations or access the network. That's basic software design 101, unfortunately not taught everywhere. I don't see this one as a clear flaw of Python. "Dumb" coding can happen anywhere. I suppose it could prohibit this kind of stuff, but that might prohibit other cool things that might be reasonable in limited situations. It is a "consenting adults" design, with those trade offs.