don't run `python my/script.py`! (beginner - intermediate) anthony explains

Поделиться
HTML-код
  • Опубликовано: 4 окт 2024
  • today I show why running `python my/script.py` is almost always not what you want and that `PYTHONPATH` isn't much better and that you usually want `python -m`!
    playlist: • anthony explains
    ==========
    twitch: / anthonywritescode
    dicsord: / discord
    twitter: / codewithanthony
    github: github.com/aso...
    stream github: github.com/ant...
    I won't ask for subscriptions / likes / comments in videos but it really helps the channel. If you have any suggestions or things you'd like to see please comment below!
  • НаукаНаука

Комментарии • 52

  • @Squeemos
    @Squeemos Год назад +35

    I gotta be honest, after coding in Python for 3 years, your videos are always something I keep coming back to for little things here or there. It'll be like "I remember Anthony had a video on this... what did he say to do again?"

  • @kent8547
    @kent8547 Год назад +7

    I just spent like 5 hours trying to get my imports working without modifying the sys path directly. This video is exactly what I was looking for. Thank ya!

  • @AZIARGROUS
    @AZIARGROUS Год назад +5

    Thanks Anthony, this is always useful! I just keep coming back to a video I have seen of yours whenever I run into these situations in "real life examples"

  • @pemessh
    @pemessh Год назад +2

    I can't believe this channel was not recommended by youtube to me for so long.
    Loving these videos. Super informative.
    Thank you so much.

  • @pythoff
    @pythoff 2 года назад +8

    Anthony, thank you so much for making these videos.
    I have been doing PYTHONPATH for my whole life and never suspected there might be something wrong there.
    If I can be helpful for any of your project, just let me know.
    Your videos are wonderful, keep the good job

  • @JohnBrown-ct7mg
    @JohnBrown-ct7mg Год назад +1

    Great video, honestly something I've been wondering for over three years and never really got to the bottom of.

  • @DavidDellsperger
    @DavidDellsperger 2 года назад +7

    don't run, I agree. In all seriousness, I've not really run into this problem, but maybe that's because I just monoscript for console script like stuff, or use __file__ vs. os.cwd when trying to deal with paths of things, but it's been a while since I've had to do any of that kind of stuff.

  • @unvergebeneid
    @unvergebeneid 2 года назад +12

    What really annoys me more than the behavior of Python when running a script is that the ratio of actual best practices to garbage non-solutions on the web is tiiiiiny! So, thank you for this video! May it blow up and be referenced from Stackoverflow or something!
    I only wish you had talked about how setup.py is outdated and that a modern package would look differently.

    • @GrzesiuG44
      @GrzesiuG44 2 года назад +3

      setup.py is not outdated. What is outdated is invoking setup.py directly - you should use external commands like `pip install` that will know to use your setup.py.
      Alternatives like poetry have a lot of benefits, and are definetly better for people starting with Python while knowing other languages and their package managers (especially npm). But using plain old setup.py+pip+venv not only is just as capable of getting job done - it has some useful quirks that you can really use if you spend time understanting them.

    • @unvergebeneid
      @unvergebeneid 2 года назад +1

      @@GrzesiuG44 my understanding is that one should at least go for a setup.cfg, if not outright a pyproject.toml. Independent of using any particular packaging solution.

    • @GrzesiuG44
      @GrzesiuG44 2 года назад +1

      ​ @Penny Lane They are definetly the future, but I expect it will take a few more years before it can be considered the way. My understanding is that currently setuptools is only on its way in fully migrating from setup.py and setup.cfg into pyproject.toml - and even once this happens the setup.py support and probably even usage for new projects will stay for a long time. If I understand correctly you can't do things like `pip install -e .` with pyproject.toml currently.
      This also is the endless battle of configuration inside code vs code inside configuration. The latter is probably cleaner (esp for 3rdparty parsers) and current trend; but makefiles and more recently cmakes show that just having a dirty mess that gets the job done might be more practical. Because sometimes you just want to have a package that collects files with even number of vowels in their filename, and puts it into package name acquired by HTTP request.

  • @ns_the_one
    @ns_the_one 5 месяцев назад

    i searched about this error so many times and tried to learn and none of the other answers helped me. Great video. Thanks a lot

  • @GrahamAtDesk
    @GrahamAtDesk Год назад +3

    I don't think the cwd should be on the import path; as the author of an import statement I want to know that the code I intend to import hasn't been overridden by the presence of a random module in somebody's current directory. The very idea that it would do this is slightly terrifying!

  • @JoeLi-im4em
    @JoeLi-im4em Год назад

    Very helpful! I spent several hours to solve this problem, and I finally solve it with your method!

  • @b_0rk
    @b_0rk 2 года назад +3

    WHY AREN'T MY IMPORTS WORKING

  • @b_0rk
    @b_0rk 2 года назад +1

    "$PYTHONPATH is almost always wrong" should be a tattoo

  • @voiceoftreason1760
    @voiceoftreason1760 Год назад +1

    I'm still going to do it. my python projects are all one big script anyway

  • @张紫-w8q
    @张紫-w8q Год назад +1

    Thanks for the detailed explanation!!! I already subscribe to your channel!!!

  • @essamgouda1609
    @essamgouda1609 2 года назад +1

    Thank you for another great video ! Very informative.

  • @pward17
    @pward17 Год назад

    currently my program is working. But ill try to do this and see if something changes

  • @abdulhamitkumru
    @abdulhamitkumru 2 года назад +1

    great video as always, thank you

  • @cyrilquijoux9149
    @cyrilquijoux9149 29 дней назад

    Can you explain the raise SystemExit(main())?

  • @tadassatafarra7503
    @tadassatafarra7503 2 года назад

    Anthony ur the mann
    Grate video with very useful info

  • @muhammadbilalshahid8010
    @muhammadbilalshahid8010 2 года назад

    Amazing work friend

  • @botman4566
    @botman4566 2 года назад +1

    literally me crying why .. and . imports dont work

  • @ayoolowoleru8251
    @ayoolowoleru8251 9 дней назад

    we learn everyday

  • @ArielVolovik
    @ArielVolovik 11 месяцев назад

    Would you still make all paths relative in your code?
    Like using pathlib to get the current path, and then going up directories from there?
    Or would you simply make all the paths relative to the main entrypoint as defined in setup.py?

    • @anthonywritescode
      @anthonywritescode  11 месяцев назад

      if they're user-specified paths (like input files / etc.) I'd take them as arguments and deal with them that way
      if they're resource files I'd use `importlib.resources` to access them and not think about the pathing or layout (it might not even be on the filesystem!)

    • @ArielVolovik
      @ArielVolovik 11 месяцев назад

      @@anthonywritescode I'm having difficulty understanding how importlib.resources works.
      If I have some dir structure like
      .
      ├── example-files
      │ ├── inputs
      │ │ ├── file1
      │ │ └── file2
      ├── requirements.txt
      ├── src
      │ ├── main.py
      ├── nested
      │ ├── dir
      │ │ ├── foo.py
      └── test
      ├── test1
      If I want to load the example-files.inputs.file1 or example-files.inputs.file2 from src/main.py, how would I do it? What if I want to load it from nested/dir/foo.py?
      I tried simply doing
      from importlib.resources import files
      f = files('example-files.inputs')
      But I get "ModuleNotFoundError: No module named 'example-files'"
      If however I run the code above from the root DIR, it works fine. Are the modules somehow relative to the "executing directory" as well?

  • @kurianbenoy9369
    @kurianbenoy9369 2 года назад +1

    Is it why python3 -m pip install package recommended?

    • @anthonywritescode
      @anthonywritescode  2 года назад +1

      I've got a video about that! ruclips.net/video/gnYdk_U6UQ0/видео.html

  • @PepeTostado
    @PepeTostado Год назад

    what is the best way professionals deal with this? I want to learn the proper way so I can Implement it on my project. Thanks Anthony!

    • @anthonywritescode
      @anthonywritescode  Год назад

      I show the alternatives! (either -m or make an installable tool)

  • @e1nste1in
    @e1nste1in 2 года назад

    Took me also a while to figure this out.

  • @hugocarr3966
    @hugocarr3966 2 года назад +1

    Would replying to a JIRA ticket with a YT video be passive aggressive? Asking for a friend.

  • @mofiro6758
    @mofiro6758 2 года назад

    Great explanation, one thing is however missed: how to import from another file inside a folder in (like a/helpers.py) in a/main.py.
    Example:
    # a/helpers.py
    def answer2life():
    return 42
    # a/main.py
    from a.helpers import answer2life
    print(answer2life())
    it looks ugly IMO when your directory is named src (instead of 'a' here). Any other way to do it?

    • @anthonywritescode
      @anthonywritescode  2 года назад

      I go over both ways in the video -- absolute imports I strongly prefer but there's also explicit relative imports
      but also your top-level module shouldn't be named `src` -- you're probably doing src-layout incorrectly: ruclips.net/video/sW1qUZ_nSXk/видео.html

    • @mofiro6758
      @mofiro6758 2 года назад

      @@anthonywritescode Thanks for your reply but I couldn't find my answer in that video. The layout I meant is something like this:
      myproject/
      requirements.txt
      src/
      __init__.py
      helpers.py
      main.py
      data/
      ...
      tests/
      How would you import functions from helpers.py in the main.py. The way that works for me (while using python -m src.main) is
      # main.py
      from src.helpers import funcA, funcB
      I would be grateful if you can elaborate what is the correct way of both doing both layout and import in this case.

    • @anthonywritescode
      @anthonywritescode  2 года назад +1

      src is a very bad top level name it should be the name of your project or a descriptive module name

    • @mofiro6758
      @mofiro6758 2 года назад

      @@anthonywritescode Thanks man, but apart from naming, is the structure correct for a simple project?

    • @Bryft
      @Bryft 2 года назад +1

      @@mofiro6758 IMO it is. I usually name the module the same way as project/git repo (only replacing dashes to underscores), e.g.
      my-project/
      requirements.txt
      my_project/
      __init__.py
      __main__.py
      main.py
      helpers.py
      data/
      ...
      tests/
      I added __main__.py as it allows creating a nice entry point to the whole with:
      python -m my_project
      Also, you might consider using requirements.txt & requirements-minimal.txt if we're talking about a project that is meant to be deployable (in contrary to libraries or tools like flake8). In the latter req file you list only top level imports as loosely specified as possible, and you use this file to easily update requirements.txt which should have all dependencies with frozen versions. This guarantees you repeatable builds

  • @cat-boy1357
    @cat-boy1357 2 года назад +1

    Im sure at somepoint, ill understand what he explained. lol

  • @sixthinsomniac
    @sixthinsomniac 2 года назад +1

    Is venv your virtualenv generator of choice? What are your thoughts on poetry/pipenv/pdm?

    • @anthonywritescode
      @anthonywritescode  2 года назад +5

      nope: see ruclips.net/video/MGTX5qI2Jts/видео.html
      - poetry: too complicated, doesn't really add anything for me, wrong about versions
      - pipenv: slow for no reason, I avoid code by the original author
      - pdm: running code blindly from working directory is a security issue -- see also ruclips.net/video/_fpXyS_i1xE/видео.html and ruclips.net/video/J7NMyb-LNX4/видео.html for similar issues

    • @MrHaste12
      @MrHaste12 2 года назад

      @@anthonywritescode you don't use requests? why and what should be used instead?

    • @anthonywritescode
      @anthonywritescode  2 года назад +3

      urllib.request works fine for me, if I need async I'll use httpx

    • @TheMicho1234
      @TheMicho1234 2 года назад

      @@anthonywritescode why poetry is wrong about versions?

    • @anthonywritescode
      @anthonywritescode  2 года назад +2

      it ~forces `~=` versioning on everything making compatibility difficult. it does this as well for `python_requires` and forces you to match the minimums of your dependencies (even if a version could resolve) -- this is why so many with poetry have `python_requires>=3.6.1` (just because a popular package of mine sets the same!). all three of these behaviours are harmful for integration between libraries

  • @michalski9141
    @michalski9141 2 года назад

    that fancy keyboard is just begging you to use vim

  • @Flippy_Nips
    @Flippy_Nips 2 года назад +1

    I can’t be the only one looking at the keyboard and not his screen.