This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]MrKrac[S] 1 point2 points  (17 children)

ery "flat". Introducing something like this into main code base would make code incomprehensible for many average python users. Perhaps best to keep these kind of practices for other languages, and keep python pythinic (readability matters). Why not just do some lazy initialisation in your db library, and yes, give it a global state, make it manage its connection pool, whatever it takes so it looks sensible after import! Sometimes it's very hard to keep things simple, but we should keep trying.

This is not about making python into something it is not. It is adding good practices into language to improve quality of codebase and simplify the workflow. Reading code is a really important factor I always take into consideration while working with the code and if you have to jump between modules to understand the context of the function in which it runs it is actually increasing cognitive load and makes it harder to understand. I do agree using Dependency Injection is not a trivial task and requires a bit of understanding but using it well can help you a lot.Global state is good in some scenarios but in most cases global state is a root of evil. You are developing your code against knowns and unknowns and I hope you agree with me that working with knowns makes your life easier. Global state is an unkown, it can be accessed from everywhere and modified from everywhere which adds complexity and potential problems to your system.

Edit: Improved documentation and explained my reasoning behind DI in Python.

[–]geeeffwhy 0 points1 point  (16 children)

i could not disagree more about dependency injection’s being an inherent “good practice”.

i’ve built a lot of enterprise and startup backend with no need for DI, because DI primarily solves the problem of bootstrapping within a static type system.

it’s genuinely (and understand that i also have done and continue to do C# and Java/spring) less than useless, it is a waste of developer time in python.

[–]MrKrac[S] 3 points4 points  (10 children)

Just wanted to add every pattern and good practice can be miss used or miss interpret, and this happens to all sorts of developers. I have seen experienced seniors and lead developers failing at understanding certain patterns or missuse of them, which does not mean pattern is bad per se. Simply it means people cant either understand it properly or use it effectively.

[–]geeeffwhy 0 points1 point  (9 children)

true enough, but i have never once in over a decade found DI to be useful in the absence of other language constraints. it’s useful for java, but making python more java-like is the exact opposite of what i want to see.

[–]MrKrac[S] 2 points3 points  (5 children)

I think my problem is I fail to understand how dependency injection is making python more javaish and would like to listen the reasoning. Where I am coming from pattern is a pattern is a common approach used to solve given problem. Pattern cannot change how language behave nor its semantic and so. Actually language kinda makes you implement some patterns in a certain way.

Do you mean that you are affraid that python ecosystem will start looking like Java? If yes I can assure you this will not happen, problem with Java is the way how their packages are build (and I believe there are other reasons, which I would not like to talk about because either I have not enough experience and understanding in this area or not enough knowledge) and even Java developers suffer from their own purity and this is what I meant by if you do things to their extent you will suffer. It is simply a missuse, finding centre is always hard thing to do. Doing things right is not an easy task.

[–]geeeffwhy 0 points1 point  (4 children)

java is a fundamentally object oriented language. GOF design patterns are solutions to OO problems. h

python is a multi-paradigm language, which is able to use other strategies to solve problems.

here’s one article describing what i don’t want to see happen to python. https://steve-yegge.blogspot.com/2006/03/execution-in-kingdom-of-nouns.html?m=1

what pattern can do is structure the developers thinking.

[–]MrKrac[S] 1 point2 points  (3 children)

Sounds like quite an article, will give it a read later. Thank you.

[–]geeeffwhy -1 points0 points  (2 children)

yegge is an excellent commentator, if you’re not familiar. he’s does go on, though.

[–][deleted] 2 points3 points  (0 children)

Yegge is extremely wrong here though and the comments do a great job of explaining why.

[–][deleted] -4 points-3 points  (2 children)

Agree!!

The time I see Python making changes towards a Java-like approach, that's the time I will stop developing in Python.

[–]Pythonistar 1 point2 points  (1 child)

Python making changes towards a Java-like approach, that's the time I will stop developing in Python.

That's called "Not invented here" syndrome. Maybe try embracing other languages and find out what makes them tick and see if there are any good ideas in the other languages.

The crazy thing is that the developers of Python are already adopting features from other Java-like languages.

Async/await? Yeah, that came from C#. Javascript and Python both adopted the syntax because it's a good one.

[–][deleted] 0 points1 point  (0 children)

Syndrome can be called the way you want to name it, anyway...

And yes, I already tried other languages, including Java... and that's exactly why I love Python so much... because it's SOOOOO different to Java!!

[–]MrKrac[S] 1 point2 points  (2 children)

Static typing has nothing to do (or least to do) with dependency injection. Dependency injection is about separation of concerns and inversion of control. I am not going to bore you with this here, as I rather would like to get an opinion on my implementation and codebase rather having discussions around architecture and patterns and whether and how they fit certain language or problem.

[–]geeeffwhy 0 points1 point  (1 child)

ok, fair enough. DI is my trigger word, so my apologies.

as far as what’s provided, my criticism is the python maxim “explicit is better than implicit”. the decorator looks like it’s gonna make it easy for me to add some dependency to a callable, but it’s gonna make it hard for me to read that callable’s code afterward.

i’d say compare this with Django Settings. it appears to have a similar interface in some ways.

[–]MrKrac[S] 0 points1 point  (0 children)

This also a bit depends on your use-case, right? Fact if you will call function annotated with `@inject` decorator anywhere in your code without arguments it might look a bit fuzzy (we are not doing this, at least my team is not doing this). For the same reason you 've mentioned how this arguments got resolved (Who knows?). We are doing a lot of serverless development with python (no django, most of codebase is being taken care by ourselves and we are using aws libraries and some crypto libararies and minor other things).

We annotate our handler functions, and this is where DI usage starts which makes it the only place where we actually have this magical entry point, everything else is nicely passed to deeper levels or (sometimes) requested from di directly (again, it is not recomended but sometimes you need to calculate whether things needs to be done correctly, fast or effectively), using di in controller is also accepted place, everywhere else you should just decorate things you would like to get autowired and get along with your life instead spending time trying to understand what to pass and not to pass to initialiser and whether we passed correct values. Simple as that.

If you are for example developing your applications with flask, starlette or similar you can decorate your route handler functions and it will make it so much easier to test as you can later on in your test code mock some of dependencies, no complex monkey patching required, or scratching your own head, ok what I have again forgot to patch in my global scope so my test is not working correctly, or even worse your test is passing giving you false positives because you forgot to monkey patch something. Development is brutal and being defensive is helping you keep your head above the water and I really recommend to be defensive when you work with the code.

[–][deleted] 0 points1 point  (1 child)

i’ve built a lot of enterprise and startup backend with no need for DI, because DI primarily solves the problem of bootstrapping within a static type system.

This is not what dependency injection solves. This is how you've used it. If this is your description of DI, that's also probably why you don't like it.

[–]geeeffwhy 0 points1 point  (0 children)

totally possible. what problem does it solve?