You know you royally f-ed up when the tutorial expert tells you "In this case, I cannot help you, good luck" :P
@daviddunleavy1873 жыл бұрын
You are the only channel that I feel makes quality tutorials for the sort of stuff that is a tad more advanced/a bit below the surface in python. I always learn something even when the video is a topic that I think I already have a pretty good handle on. Thanks!
@nathanoy_2 жыл бұрын
fully agree^^
@pranavnyavanandi97102 жыл бұрын
mCoding is like the Stack Overflow of KZbin. 😄
@Zokrar3 жыл бұрын
"Your application needs some SERIOUS redesigning, it's going to be a mess no matter how you do it" Somehow hearing James say this is even worse than "I'm not mad, I'm disappointed" from a parent
@mCoding3 жыл бұрын
Everyone writes bad code sometimes! I would never be disappointed as long as you recognize the error and *learn* from it.
@YeOldeTraveller3 жыл бұрын
@@mCoding I once had an instructor in a Computer Science course state they he never wrote bad code. I switched to a new section the next day. He had just told me he did not write code. (Or he was lying)
@ChristianBrugger3 жыл бұрын
@@YeOldeTraveller In a univeristy setting, his statement makes sense to me. What I have seen is that 25% of the students don't get coding and write code so bad that it is really shocking. And he probably never wrote code of such quality. I think that is what he is referring to. James is referring to something completely different. Writing code that you find deeper into the project bad. This happens to everyone. The former not always.
@Mutual_Information3 жыл бұрын
I had this problem a few months back and when asking coworkers for how they solved, no one had good answers. Everyone seems to just guess around until things works. Nice to have a solution like this.
@mCoding3 жыл бұрын
Feel free to share this video with all your coworkers!
@theepicguy65753 жыл бұрын
HOW!, such perfect timing, been breaking my head for the past few days over a circular import!
@mCoding3 жыл бұрын
Hope this helps you resolve it!
@theepicguy65753 жыл бұрын
@@mCoding yup, instantly solved 50% halfway thro the video, just TYPE_CHECKING for one, and some dynamic imports :3
@hellNo1163 жыл бұрын
i love that you closed the video with exactly the phrase any sane person would give to someone who loyally screwed up and you didn't sugar quoted.
@robmckiernan32643 жыл бұрын
😅 Sugar quoted. Sugar coat it
@mCoding3 жыл бұрын
Sometimes that's the way it goes, better to recognize it and do what you can to move on!
@ShiroMZM3 жыл бұрын
Wish I've seen this some months ago. I did the "serious" re-design because of type checking. never the lesss, I did end up with a module design that's quite complete so that's a win :D
@QuantumHistorian3 жыл бұрын
I think gold rule is: _Don't have code in one module that runs code from another module at import time_ . The only reasonable exception to this rule for libraries, IMO, is if you have one module that defines classes that inherit from another module. In this case, you have to divide the various classes in the inheritance chain between different modules in a sensible way.
@mCoding3 жыл бұрын
Great tip! I want to emphasize that I agree that the best thing to do is avoid running code at import time in the first place.
@QuantumHistorian3 жыл бұрын
@@mCoding Sure, except that for running things like function and class definitions (and class attributes) it's utterly unavoidable. But the only one of those that has any business importing from other modules are parents in class definitions. And maybe decorators in some cases.
@xelaxander3 жыл бұрын
@@mCoding Oh god yes! I came across a project that did this recently. The authors just loaded ~10GB from disk, reformatted the data and dumped it again.
@megaing13223 жыл бұрын
I can't really a situation where the last example you showed is relevant, but there is one general fix you can try: moving the `from ... import ...` statements, and everything that directly depends on them at import time at the end in both files. While that violates PEP-8, it often works. This is also a quick fix for almost all the other situations you mentioned.
@naalul3 жыл бұрын
Another way would be to extract whatever is the reason for the circular import (in this case module_b.func_b2 that depends on module a) to a third module
@AntonioMellor2 жыл бұрын
Thank You! I know this vid is older but it popped up as recommended so I watched it a week ago I think. Today I had this exact problem with type hinting and I remembered this video. some of the best Python content being made!
@anatolytsi3 жыл бұрын
Had a circular import error just yesterday, very relevant :) Had a loader script, which would store the class type of other module class that inherits from other script class, which in turn was using global variables from loader script. Fixed by moving the globals to a separate script file accessible for every script It is definitely an architectural problem most of the time :)
@sohangchopra64783 жыл бұрын
You might want to consider getting rid of globals entirely - they are (generally) a bad idea. Note: By globals, I mean global mutable variables, not constants (which are never mutated after assignment).
@anatolytsi3 жыл бұрын
@@sohangchopra6478 sorry, my bad, I meant constants, of course :) Completely agree on your statement and never use global variables
@liude77653 жыл бұрын
Generally, circular dependencies are a sign of bad design, with at least one principle being violated, most often those of single responsibility, low coupling, and layering. This might be ok for small applications, and might not lead to problems right away even in larger ones, but over time as the system grows it's bound to lead to issues. The worst part is, in circumventing these issues developers often introduce worse and worse patterns, eventually leading to largely unmaintainable systems and mountains of spaghetti code. If you're running into issues like this, some architectural redesigns are definitely needed, and should be done sooner while the codebase is small rather than later if the project is intended to be a sustainable long-term.
@drygordspellweaver87612 жыл бұрын
Cough Selenium Cough
@PatriciaOsifo2 жыл бұрын
@Liude, could perhaps suggest some resources to learn about design principles or best design architectures? For me, I was working on a task that required a certain program structure. I submitted something with a different but I think, better structure, but it was rejected. So, I needed some way for the app to work without errors in that structure. And this was really helpful for that. Sometimes, we can help what the client wants.
@jakobullmann75862 жыл бұрын
@@PatriciaOsifo Cycles are pretty evil. JetBrains IDEs have a function to visualize dependency matrices. No cycles means the matrix should be lower-triangular. As a rule of thumb, lower level functionality should be independent of higher level functionality (and if A depends on B and B depends on C, try to make A to depend on C only through B). If you cannot avoid cycles, at least keep it to class cycles and avoid module cycles at all cost, because they will make refactoring impossible. Static analysis tools like SonarQube can also help. Otherwise I’d recommend read about clean code and software architecture.
@PatriciaOsifo2 жыл бұрын
@@jakobullmann7586 Thanks a lot for this!
@NicolasChanCSY2 жыл бұрын
I am working on a Selenium automation project recently and I use page object model ("POM") to manage the different pages. Since POM encourages page objects to return another page object when navigating to another page, I run into circular import, when two pages navigate bidirectionally. Glad that I remember that I saw this video a few months ago and can come back for your great tips and insights! Now I understand the issue better. In my case, I shall use your suggestion in video chapter "Subpackage init cycle" with the interface directories. Thanks again!
@drygordspellweaver87612 жыл бұрын
Selenium itself is a mountain of spaghetti code. My script suddenly started taking 45 seconds to load and I didn’t change anything .
@NicolasChanCSY2 жыл бұрын
@@drygordspellweaver8761 I just treat it as a black box when using it 😁. However, sometimes, I do hope that Selenium can have clearer documentations. And most StackOverflow answers are using Selenium
@DanielLavedoniodeLima_DLL2 жыл бұрын
I remember that Flask had some kind of circular dependency issue when you try to separate the project into an MVC architecture with multiple unit components in different folders. I used it more often a few years ago, not sure if they overcame that issue in the newer versions
@mCoding2 жыл бұрын
I know exactly what you mean and no they have not solved this. It's not really something they can solve bc at its heart the issue is that the shortest simplest way to build an application that they encourage in all their examples naturally leads to cyclic dependencies if your application gets even slightly larger. The real solution is to encourage users to not use global variables for defining all their views/blueprints and instead keep everything inside functions and use locals. It's may look like "more work" and "not as pretty" and "over engineered" but trust me it will save you many hours in the long run!
@MechMK12 жыл бұрын
I recall my professor saying "If Foo needs Bar and Bar needs Foo, then the two belong together. Who are you to separate two lovers?"
@taneliharkonen24633 жыл бұрын
Simply the best video on utube on import loops! That was so thorough!! :o :D
@barterjke2 жыл бұрын
When i starting to feel that i know everything about python, your chanel come and crush my confidence.
@sebastiangarciaacosta54683 жыл бұрын
I love you, thanks for all the great content.
@mCoding3 жыл бұрын
Many thanks for the kind words!
@Scranny3 жыл бұрын
Is it best practice when using type hints to *always* put the type imports under the "if TYPE_CHECKING" clause regardless of cyclical imports? (For purposes of readability and a way to announce that those imports aren't importing any functionality?)
@mCoding3 жыл бұрын
Great question! I personally do this out of habit, but I don't think I would call it a best practice so much as defensive programming.
@KappakIaus3 жыл бұрын
I was looking for this question, nice :)
@hedwinbonnavaud6998 Жыл бұрын
Thanks a lot for this calm, clear, and complete tutorial
@richardcoppin53322 жыл бұрын
I'm my experience 'real' circular dependencies tell me that you probably need a third module (possibly containing an abstract base class). Out may not solve every issue, but is definitely worth exploring.
@arceusmewtwo77742 жыл бұрын
Thanks a lottt man , this helped me solve a major problem in my project (application)!! I'll definitely mention u in the credit section of the application
@sawcondeez3 жыл бұрын
Does Python reimport the module again when it is declared inside the function? From the video @ 2:02, does Python reimport func_b1 from module_b again when func_a is called the second time?
@brunoais3 жыл бұрын
No. Python caches imports by default. You can use internal APIs to order python to forget a cached import, though.
@kelpie6902 Жыл бұрын
This is so unbelievably helpful
@HadesMrDark2 жыл бұрын
This was a great watch, thank you so much, for sharing with us your knowledge.
@jurgenrusch40413 жыл бұрын
Hi, I love your channel and I wish this video on circular imports had been there 2 years ago when I was struggling with exactly the topics you have treated here. Thanks for the clear explanation. And keep those videos coming!
@yash11528 ай бұрын
5:31 where is main.py residing?? i cant figure it out in this project view of jetbrains ides pycharm
@ChristianBrugger3 жыл бұрын
Great video. Didn't know the trick with the interface module. Saw it on some open-source projects and was wondering why thy do it.
@mCoding3 жыл бұрын
Glad you liked it! Some packages also use the "module" vs "_module" naming convention for having a native C module with the underscore and no underscore for the interface. This is seen a lot in CPython standard library itself.
@fat_pigeon3 жыл бұрын
Another technique if your dependency is needed only inside a function is dependency injection. e.g. ``` from . import logging def foo() -> None: logging.log("foo") ``` => ``` from typing import Callable def foo(log : Callable[[str], None]) -> None: log("foo") ```
@amgg_3 жыл бұрын
something probably worth noting, instead of using `from __ future __ import annotations` with `typing.TYPE_CHECKING` you can just manually make them strings (and in fact that's what you'll need to do if you're below 3.7)
@Scymet Жыл бұрын
It's ugly tho
@reddragon31323 жыл бұрын
In reference to the from __future__ import annotations, what determines the 'future'. Is this a feature that is currently scheduled to be in a future python release (or is in an already released later version)? In which case when will this annotation behaviour become the default?
@mCoding3 жыл бұрын
docs.python.org/3/reference/simple_stmts.html#future-statements Typically yes. It is to allow opt-in changes that are backwards incompatible for things that are expected to become the default in future versions of Python. Though "expected" may change, as may be the case soon with annotations.
@lex_darlog_fun3 жыл бұрын
What about `__all__` for sub-package cycle ? You can have modules defined in `__all__` of package's init. That way you have both benefits: you can do `import *` while also avoiding a circular dependency.
@mCoding3 жыл бұрын
The `__all__` variable won't help you avoid import cycles as it only affects what happens when you use "import *", whereas all the import cycles presented in the video don't even use "import *" at all. It could help you litter your namespace less than if you didn't use it when you "import *". However, it would still be better to just import the things you actually need.
@peter.wilson12 жыл бұрын
The whole point behind modular boundaries is to say Is to guarantee that all resources needed are imported and are made to work in isolation relative it to it’s dependencies. So in the case of a module being a sub module it could make sense that you might want to reference the Ancestor modules, But what it seems to make more sense is that you were to have a module that specifically deals with that interrelationship an imported in both places. I think that would be a more stable solution that avoids breaking the dag model of modules. Another thing to avoid in general with most programming language is the concept of accessing global variables. Globals will get you every time. One problem with globals in most languages is you cannot guarantee their initialization order unless you’ve seen it yourself. If you do use a global variable and it’s in a separate compilation unit the loading sequence could be out of order in causing undefined behavior.
@zapshadab3450 Жыл бұрын
Thank you for giving solution for these types of errors
@Articha3 жыл бұрын
I'm doing some pet-project, and met import cycle. Thanks, James Murphy, u nearly save my project
@Jmignet3 жыл бұрын
Great video! I was curious about your mention to "import time". I tried to google it, but Google thinks I am asking about the time library. is there any other terminology I could use to research that subjext?
@mCoding3 жыл бұрын
By import time i just mean the time that a module is imported. This is when functions and classes are typically defined, rather than when you call your functions or create instances of your classes. The term import time is not formally defined, it's just a colloquial term.
@PatriciaOsifo2 жыл бұрын
This was really a lot of help! THANK YOU!
@aDifferentJT3 жыл бұрын
All of these violate layering and so I’d generally want to redesign all of these.
@mCoding3 жыл бұрын
Hmm could you elaborate? An example might help me and other readers to understand your approach.
@Techiesse3 жыл бұрын
@@mCoding Divide the application in layers each with different levels of abstraction. At the bottom we have infrastructure functionality and at the top we have user interaction. The golden rule is: no layer is allowed to access anything from upper layers ( they can only look downwards). Ex: the code that writes a file to disk is not allowed to change the color of a button on the UI. If such a feature is needed it must be done via a callback.
@sohangchopra64783 жыл бұрын
@@Techiesse That sounds similar to how Computer Networks are designed - there are different layers (see OSI Network Model), each of which performs one type of task. The higher level ones depend on lower level ones.
@Techiesse3 жыл бұрын
@@sohangchopra6478 Yes, the difference is that in the OSI model each layer has a very specific role, while in application design the layers can be anything (I was not very accurate in my first explanation :) ) as long as they follow the rule. Usually they tend to fall in this infra -> UI paradigm and then become similar to network architectures.
@astronemir3 жыл бұрын
@@Techiesse thank you this is really interesting. Is this a design pattern that one can read more about?
@mishikookropiridze3 жыл бұрын
Interface module is interesting.
@tsunekakou12753 жыл бұрын
remind me of #include, the separation of declaration and definition in C and C++. I wonder what happened when C was designed back in the 70s and how C++ address this in C++20 module.
@mCoding3 жыл бұрын
Indeed it was a similar problem that led to the separation of declaration and definition in C (can't define mutually recursive functions without forward declarations). As for C++, C++20 modules are "imported" at compile time, so any cycles are resolved before runtime.
@nickgood60882 жыл бұрын
I don't get the part where modules depend on their __init__ files, does anyone know the subtley of that? It's not like the modules are importing their init right?
@baronbacku99843 жыл бұрын
i love this channel so much
@namdao2672 Жыл бұрын
i'm straight up putting this in my bookmark
@davea136 Жыл бұрын
When James says "Good luck" that means "don't do this." Listen to him.
@not_vinkami3 жыл бұрын
Will importing at runtime be slow? I feel like that is clean to use but I'm a bit afraid of its consequences in execution time
@mCoding3 жыл бұрын
Imports are cached in sys.modules so the runtime import will only actually run once, meaning there will be no meaningful difference in execution time from executing the function many times.
@not_vinkami3 жыл бұрын
@@mCoding oh that's nice! I thought I'd need to manually cache the module somehow. I love Python
@johnnytoobad77853 жыл бұрын
I first had this problem while writing python back-end code for a tkinter based gui-app. The main gui mod was "importing" back-end (command-button callback) code. No problem. However I also needed to update gui attributes from the back-end import. (ex. a status message line) I attacked this problem by loading the gui widget ref's into a dict which gets copied (loaded) to the back-end import from the main gui driver module, just after the gui performs its own initialization. Now the back end has access to ALL public gui attributes via the individual gui widget refs from the copied dict. BUT...You need to null out these extra (back-end) ref's BEFORE the main gui widgets get destroyed. You can use this technique for any type of "object" (defined in the driver module) that the "imported" module needs to access. It's kind of indirect but it works just fine. In this case the dict.-of-widget-refs acts as the "interface".
@mCoding3 жыл бұрын
Thanks for sharing!
@johnbennett14653 жыл бұрын
Having had some nasty cyclical dependencies, here is a last resort method that can resolve some types of loops. - Remove the import of A from B - A imports B - Finishes initializing itself - At the end pokes its needed members into B - Finally it calls an initialization function in B that allows it to fix up any dependencies on A This is extremely ugly and should only be used when cleaner options won't work. I have been backed into this corner once. I tried several other options, but in the end this was the only way I could get it to work.
@mCoding3 жыл бұрын
Hey, it's not always feasible or worth your time and effort to fix old code (that may not even be written by anyone still around). Do what you gotta do and if a quick and dirty fix does the job, that might be the right answer for your situation.
@ManuelBTC213 жыл бұрын
Rules of thumb: - Only import modules directly `import x.y` - For common imports, shorthands `import x.y as z` can make sense - For common types create a module project/common_types.py and import with `import project.common_types as ct`
@drygordspellweaver87612 жыл бұрын
And if the module you’re importing is enormous? Say, Selenium or Tensorflow
@sergio20r Жыл бұрын
I'm a beginner at programming. There's something about TYPE_CHECKING that I didn't fully understand and hopefully you could help me: We are still importing class B from module_b and then class A from module_a so tecnically the code will still crash, right? Or it won't since it's purely a test with mypy?
@youcamp1322 жыл бұрын
I'm new to python so this might be a stupid question. Why wouldn't you just check if the module is already imported before importing it? As in this example: if 'ModuleName' not in dir(): import ModuleName Which also raises the question why doesn't import do that automatically? Am I missing something?
@mCoding2 жыл бұрын
Python does check if a module is already imported before importing it. The issue here with import loops is when you try to grab a value out of a module that has not finished importing when the value has not yet been defined in the module.
@youcamp1322 жыл бұрын
@@mCoding Ah okay, good to know. I was missing something. And thank you for your response.
@yash11528 ай бұрын
7:58 hmm, a yet another new thing specifoc to packaging learnt interface packages with no modules, but defining inits
@kennyostrom30982 жыл бұрын
I just saw this video. Regarding the runtime import inside a function, pep8 and pylint hate that idea. Any thoughts on why, and why is it okay in this case? You do avoid the issue using the other option, but you lose the runtime benefit you mentioned. Nevertheless, I am uncomfortable with the style guide violations not even being mentioned.
@koenbrink3 жыл бұрын
Could I just ask, why isnt the "from module_a import something" just a thing the compiler uses to then read it as module_a.something every time 'something' is written in the file? Apparently a from statement is different, but I always thought it worked as I described above. Which begs the question: are from statements better in any way? (faster for example), otherwise, there is literally no reason to not convert all from import statements to what I described so we never get these circular import errors right?
@alagaika85152 жыл бұрын
There is a slight performance penalty with writing module_a.something every time you use it instead of importing the name "something" directly (essentially the time it takes to look up a key in a dictionary). If you import a module, you have that module in your available names and can, at any time, look up names inside the module. If you directly import a specific name from a module, you have that specific name available and do not need to look it up anymore. (or, more specifically, you only need one lookup directly into globals() instead of one lookup into globals() to get the module and one lookup into the module to get the element).
@RoamingAdhocrat2 ай бұрын
I got a very weird import issue yesterday - no error message but my tests failed with results like `AssertionError: assert MyObject(id=42) == MyObject(id=42)` where one was returned by the code under test and the other was made in the test function. making every __init__.py blank and using fully qualified imports fixed it. but I'm gonna use that interface subpackage idea
@Victor_Marius2 жыл бұрын
Is it any performance improvements in importing only a function / class instead of the entire module or benefits (excepting the fact that you won't have to prefix all your function calls from that module)?
@mCoding2 жыл бұрын
When you import a single function, Python still imports the entire module it came from. The savings (miniscule) comes from the fact that when you do mod.func this is essentially a dictionary lookup of mod inside the current module then a ductionary lookup of func inside mod. Whereas if you bound func to the current module, then referring to func only incurs the name lookup of func inside the curent module, saving 1 dictionary lookup. This will be a pretty miniscule savings though and not a reason to do it one way or the other.
@psuw Жыл бұрын
Awesome video. Sub guaranteed.
@mCoding Жыл бұрын
Much appreciated!
@markprado37592 жыл бұрын
another way to fix this on top of my head, is to better setup the architecture of your file structure. i dont do chain imports, make sure all other module does not import each other. you should have entry point like app.py then you import a middle man module which does all your logic and from that middle man module you call the imports, and usually those modules are in separate bin/ folder. So the structure looks like this: app.py src/ - middle_man.py - bin/ -- mod_a.py -- mod_b.py
@drygordspellweaver87612 жыл бұрын
Yeah but then you’d end up with 3 or 4 middle man modules unless you want 15,000 lines of code in one module. Leading back to exactly the problem of circular imports.
@md2perpe3 жыл бұрын
Sometimes it can help moving import statements to the end of a file.
@mCoding3 жыл бұрын
True true! People will wave PEP8 violations at you, but sometimes this is the easiest thing to do!
@bruradagast3 жыл бұрын
your last example with global variable is daily reality for anyone working with Flask or similar frameworks that heavily rely on function decorators that use global variables. So, did you just call all Flask ecosystem crappy code? :D seriously, thanks a lot for the video, very insightful!
@gregorymorse84233 жыл бұрын
Not mentioned: use the AST parser to write a program which generates a module import graph to detect most cases (non-dynamic load) circular imports with static analysis without running anything in huge projects even. You need to build a graph and do a depth first search or topological sort to check for cycles. How come such a simple python script doesnt exist? I wrote one to detect recursion, I might extend it fir this
@mCoding3 жыл бұрын
It probably does exist 😅. If you do make one yourself be sure to check out the TopologicalSorter introduced in Python 3.9!
@arthurletrehumain3 ай бұрын
If you want to define your class thought multiple files, consider using mixins
@mohsenhassani4952 жыл бұрын
You are amazing man!
@mCoding2 жыл бұрын
Thank you!
@XCanG2 жыл бұрын
One method that is not mentioned here is creating *submodule* just for intersected functions of code, usually I name it like *util.py* What I do is put those intersected code in util submodule, then from both modules I import desired functions from util submodule. Since there is only one direction of importing, then there is no that kind of issue.
@acikast2 ай бұрын
great video, thanks a lot!
@abhi68532 жыл бұрын
great video ,super explaination
@mCoding2 жыл бұрын
Thank you!
@calmpuffin3 жыл бұрын
THANK YOU
@drygordspellweaver87612 жыл бұрын
I found my Selenium script taking 45 seconds to load instead of 4-5. I’m assuming it’s some weird circular import but it was working fine the day before. Totally stumped.
@yardez59903 жыл бұрын
thank you for your lessons)
@MrPatak0073 жыл бұрын
But shouldn't you avoid circular dependencies in the first place? If some components of your code are circularly dependent it creates difficult to read spaghetti code and makes adding functionality an exponentially larger process the more code you have.
@mCoding3 жыл бұрын
Yes, you should avoid circular dependencies in the first place if you can. Unfortunately in larger projects with many contributors this is harder than it sounds. Furthermore, as i showed in the video, it is possible to end up with a circular import without having a circular dependency due to type hinting.
@astropgn2 жыл бұрын
In practical use, how can A ever be created if it needs B and B needs A?
@AntonioAndrade3 жыл бұрын
Thanks 😊
@friedkeenan3 жыл бұрын
is the audio slightly desynced for anyone else?
@mCoding3 жыл бұрын
Yep, new camera setup and I didn't notice until it was too late.
@Desslosh3 жыл бұрын
So THAT's what the __init__ files are for!
@amidfallen2 жыл бұрын
Since you have mentioned packages, what about making video about them? :)
@mCoding2 жыл бұрын
I say a fair bit about packaging in my automated testing video, you might want to check that out!
@reefhound990210 ай бұрын
I really only encounter this in library modules, such as a module of stringLibrary functions that might need something in listLibrary, then something in listLibrary that might need something in stringLibrary. One big library would solve the imports but the whole nonsense could easily be handled by Python. Simply keep track of what has been imported and if something has already been imported then ignore that import.
@mCoding10 ай бұрын
It can definitely be solved in a few different ways, but it's slightly more subtle of a problem because Python *does* already keep track of if something has been imported and ignore it if it has already been imported.
@reefhound990210 ай бұрын
@@mCodingif it did then why is there a "circular reference"?
@falxie_3 жыл бұрын
I've noticed this a lot in the JavaScript world
@huzzah3234 Жыл бұрын
Someone please help me, my brain is pure mush. I am looking over and over at the interface package example, and I'm not saying it doesn't work, but I simply cannot comprehend why it works. How is the interface package any different from just the regular package? Main -> B -> IB -> C -> IA -> A -> B just seems the same to me. ---------------- Edit ---------------- (I am sure I myself will be looking for this comment many times in the future...) I was sort of right. If you do the interface package thing, and then in B.py you try to "from ..a import C" and in A.py you try to "from ..b import B", you will fail all the same. This is what was wracking my brain because I thought this was just supposed to work, but no, it doesn't and it's not supposed to. What the interface package model provides is the ability for all those subpackages to refer to each other without their actual package's initialization code, which can then be transferred to the interface package. So, inside the package, just refer to them through the packages themselves (like, in B.py: "from .._a.A import A"), not the interface. Outside the package, refer to them via the interface.
@huzzah3234 Жыл бұрын
Update - I found my own comment now that I got confused again. Thank you past me!
@misaalanshori3 жыл бұрын
I never thought this would be a problem lol
@dr.mohamedaitnouh4501 Жыл бұрын
I have constantly this issue and your video shed some light but does not resolve the problem. I am still struggling to remove it. I am wondering why they say Python is easy. Python's inventor could remove this stupid circular import that is giving pain for beginners.
@gregorymorse84233 жыл бұрын
If your module has code in it not just definitions, then many of these solutions would not work. It's the last case in the video though, as he said it's a disaster case
@AveN7ers3 жыл бұрын
Heh I experienced this circular import problem this week, only in TypeScript not python. It confused the hell out of me.
@arinzeaguolu13413 жыл бұрын
Had this issue in a flask app I was working on had to use call-time
@nightfox67383 жыл бұрын
python needs include guards or pragma once like c...
@freesoftwareextremist81192 жыл бұрын
I love watching these videos and then laugh about how stupid python is!
@Cucuska23 жыл бұрын
There is a slight lag between your voice and the video I think.
@mCoding3 жыл бұрын
Switched cameras and didn't notice this. Thans for pointing this out!
@tezz-io3 жыл бұрын
Header guards
@Cassiusisback2 жыл бұрын
#pragma once :)
@mCoding2 жыл бұрын
Python actually implements pragma once via sys.modules, which prevents you from importing the same module twice (unless you delete it)! The issue is because python imports happen at runtime whereas C/C++ imports/includes happen at compile time.
@ej32813 жыл бұрын
Importing code from within a method seems like a code smell
@ej32813 жыл бұрын
If you're missing a library you should get to know before you use the method that needs it IMO
@mCoding3 жыл бұрын
If you would like an error for a missing library at runtime, then you should use the option #2 of just using raw imports instead of from imports. However, the purpose of this video was to help you avoid import cycles in your own projects, so it is very likely that all modules that are part of any cycle are all modules within your own code, so there is no chance of them being missing. If you manage to get an import cycle between someone elses code and your code, that's a whole new kind of monster 👻
@drygordspellweaver87612 жыл бұрын
No it’s a good solution. Take my use case for instance where I need to import tensorflow to run a predictive model in just one of my functions that may or may not be called. It saves 2-3 seconds everytime I need to start the program.
@sambit982 жыл бұрын
This is
@26-dimesional_Cube3 жыл бұрын
A hacker give this code to you def password(str_input, str_key): -> int Password_num = 0 str_key_len=len(str_key) str_input_len=len(str_input) for i in range(str_input_len): Password_num += str_key.index(str_input[i])*str_key_len**(str_input_len-i-1) return Password_num This function can take a string and output the password needed to protect the string Puzzle: Make a inverted function where argument are password and str_key Input: Line 1: password Line 2: str_key Output: A string Constrains: str_key cannot have duplicate letter and must have at least character within the str_input
@drygordspellweaver87612 жыл бұрын
Bruh this is Python. You don’t need to do “for I in range(len(string))” Just “for letter in string” works. Strings are iterable.
@CAMOBAP7953 жыл бұрын
Thanks for the video timing is perfect! But to be honest, all solutions looks ugly, I really dislike python because of these import issues
@luizzeroxis3 жыл бұрын
Yeah, but what alternative is there? Python has the best import system I know, so I'm not sure many of these problems can even be ever resolved.
@gubigm3 жыл бұрын
So the solution is that there is no solution...
@markcuello52 жыл бұрын
HELP
@零云-u7e2 жыл бұрын
Also known as a cluster @__&##@#!!!! How do you even get your code so janky? You cannot dynamically unload libraries so consider how bad performance is with in-code loading. In my mind, future importing presumes a class that may rarely be used, depending upon end-user behavior or more importantly, plugin architecture. What happens when C++ code performance tweakers mess up OOP object lifetime concepts in Python.
@lunarmagpie43053 жыл бұрын
Discord gang
@mCoding3 жыл бұрын
Hello!
@КирилоХацько2 жыл бұрын
AWFUL! Python developers MUST work some time in "enterprise" language. Or at least in web stack. DI come long way from theory pattern to a tool with dosens of features
@marcus_173 жыл бұрын
The fact that this is even a problem, IMHO shows that Python isn't designed for software with 100+ lines of code.
@mCoding3 жыл бұрын
I don't see how these are related, this is not a language specific issue. C has the same problem with function definitions. If f uses g and g uses f (e.g. in mutual recursion), you're in trouble because whichever one you try to define first needs the other, which isn't defined yet. C solves this problem by adding in function declarations without implementations, which is effectively the same solution as the first one presented here for Python, which basically comes down to "it will be there when it's actually needed, don't worry about it now." Most languages share a lot of the same problems and have similar solutions to those problems when you really look into it.
@AnimeGIFfy2 жыл бұрын
worst part of python right here. like holy sh1t
@SkyyySi Жыл бұрын
Only that this was dressed with PEP 690...
@glorytoarstotzka3303 жыл бұрын
little suggestions, instead of calling them "func_a" and "func_b" I think it would be easier to follow along if they were called literally "first" and "second", at least for me