10 ms·
> There should be one-- and preferably only one --obvious way to do it. This is so hilariously wrong in python though
by Loeffelmann 3y ago
> There should be one-- and preferably only one --obvious way to do it.
This is so hilariously wrong in python though
- isitmadeofglass 3y ago[dead]
- EdwardDiego 3y agoWhatever in the NamedTuples do you mean?
- KptMarchewa 3y agoThere is also TypedDict, Pydantic, Attrs and dataclasses
- EdwardDiego 3y agoYep, but couldn't be bothered typing them all :D
- thesuperbigfrog 3y agoAs evidenced by the unified Python library / dependency management system.
- shpx 3y agoI use pip 100% of the time
- thesuperbigfrog 3y ago>> I use pip 100% of the time What about pipenv, poetry, conda, setuptools, hatch, micropipenv, PDM, pip-tools, ActiveState platform, homebrew, or your Linux / BSD distro's package manager?
- bsder 3y agoAs much as I love to rag on things, I would go so far as to say that the big problem with Python packaging is the fact that it tries to manage C/C++ packaging and integration. If Python is only managing Python code, the issues to be solved are VASTLY simpler. Just about anything works. Once it has to deal with dynamic libraries, compiled code, plugins, build systems, etc. the combinatorial explosion just makes life suck.
- thesuperbigfrog 3y agoPython is a victim of its own success and versatility. It has become a better "glue code to solve your problem" than many other solutions and so people want to use it everywhere for everything. It gets packaged in many different ways because it gets used in many different ways for many different purposes.
- bluGill 3y agoPackaging is a difficult problem and all attempts to simplify things fail to understand how complex the problem is and so fail in some way. (Attempts like .deb do okay by only focusing on a subset of the problem)
- shpx 3y agoI use none of those except for homebrew, but I didn't mention it because it's for installing complete programs that happen to be written in Python, not Python dependencies for when I'm working with Python.
- what-no-tests 3y agoYou forgot about egg!
- selcuka 3y agopip (with venvs, which is a built-in Python feature) covers 99% percent of all use cases. Yes, its dependency resolution could have been better, and lock files are nice (which can be emulated using constraints [1]) but I don't understand why people are so busy writing alternatives. I work on pretty sophisticated codebases on a daily basis and haven't used anything but pip. [1] https://pip.pypa.io/en/stable/user_guide/#constraints-files https://pip.pypa.io/en/stable/user_guide/#constraints-files
- bowsamic 3y agoGood for you but many don’t. Most people I know use Anaconda and install things with Conda
- gaganyaan 3y agoUse Poetry to produce a lockfile (or whatever lockfile-producing tool you like), and then let Nix take the wheel. It solves the dependency problem not just for Python, but for your entire stack. I've been able to hand it off to my coworkers and have everything just work with a simple "nix-shell" command, even with a dependency tree chock full of gnarly ML libs.
- kemayo 3y agoThere's generally one obvious way to do it. There's almost certainly other ways to do it, and those other ways might be better suited for different specific tasks, but the obvious way tends to exist and be widely usable. Are there some exceptions? Sure.
- rout39574 3y agoI'd suggest "pythonic", rather than obvious, for that sentence. It's one of the ways the community reminds itself of the utility of consistent discipline.
- kemayo 3y agoIt's perhaps worth noting that the next line of the Zen of Python is: "Although that way may not be obvious at first unless you're Dutch." (I.e. unless you're Guido.) So it was a bit of a tongue in cheek statement from the very beginning. :D
- rout39574 3y agoSo I imagine you have that perspective because you started less than 20 years ago. In some ways the idea of the Pythonic Way to do things evolved in opposition to Perl's vigorous advocacy of More Than One Way. Python has been really winning for some time, so it's natural that its ideological discipline has grown ragged. The crop of kids who value options above consistency don't have the scars of the Perl age to inform their prejudices. But Python is -dramatically- better focused, as a community, on finding a Pythonic way to proceed, and then advocating it, than previous cultures.
- kbenson 3y ago> But Python is -dramatically- better focused, as a community, on finding a Pythonic way to proceed, and then advocating it, than previous cultures. I would revise that to be that the pythonic culture of one acceptable way to to is better matched with a lot of good development practices. Perl was also very good at finding a Perl way to proceed. It's just that with Perl that often mean a lot of implicitness and "do what I mean", and multiple ways to do it so you could fit it within your preferred style and tailor it to the current project's needs. That all sounds good until you are confronted with the flip side of the coin, which is that it's harder to understand when looking at something written with those perspectives for the first time or after a long hiatus from the project, which puts a lot of importance on policy and coding standards which saps effort from just getting something done. I love Perl, and it's still the language I write most often for work, and it's no great mystery why Python became preferred.
- gabereiser 3y agoNot just practices, tooling. The whole typing system. Linting to check for mistakes. For the love of black.
- KptMarchewa 3y agoPython's static typing still feels very very clunky and bolted on, and tooling around it was rather bad, like mypy. In general I definitely wouldn't say python tooling was good. It's improving rapidly with ruff tho, just as JavaScript when esbuild appeared.
- jacurtis 3y agoThat was the one mantra from the zen of python that I always laugh at too. Because my #1 complaint with python is that there are so many ways to do the same thing. It sounds nice in theory if you are a new developer because you can create your own voice in python and character. For example, lets say I gave a simple coding puzzle (think leetcode) to 10 python engineers. I would get at least 8 different responses. A few might gravitate around similar concepts but they would be significantly different. By comparison if I gave the same puzzle to some Go engineers, all of the responses would be probably very close to identical. This sounds fun as a new engineer, like this is an argument for using Python. But as you get older and more experienced you will likely find yourself hating the flexibility of python because as you scan any decent size codebases, you start to be able to identify entire parts of the codebase and who wrote them, without even needing to do a git blame. I am currently an SRE manager who works in a very polyglot environment (primarily Node/js, bash/sh, python, and Golang with just enough java thrown in to ruin your day). When I read through python codebases, I can identify exactly who wrote it, even past employees. Then when you need to fix it, you often have to adapt to that style as you fix a bug or add an updated feature. This is a little true with Bash because you will see certain engineers always lean towards sed and others towards awk and grep to solve problems depending on their strength, but it is less significant. However, in our Go codebases, everyone writes nearly identical code. I've been writing Python for over a decade and I still learn new features of the language every week or month. Just this week I had to dive into the `ast` library (abstract syntax trees) which was a native module I haven't ever touched before. By contrast, I haven't had to learn any new core syntax and tools of Go and Bash in a long time. You have a fairly small set of syntax and that's it. The power comes in how you use that small set of tools, not learning a new language module. Again, the infinite flexibility sounds nice. But in a corporate environment the strictness of other languages is actually a benefit because it keeps everyone following the same path. I truly believe the mantra from zen of python: > There should be one-- and preferably only one --obvious way to do it Sadly, Python lost this tradition far before I ever became acquainted with the language. And the python3.10+ mentality of supporting everything forever is only going to make it worse overtime.
- lmm 3y agoEither you move with the times or you become obsolete. 20 years ago Python codebases were clean and consistent, but language design has moved on, and Python has - barely - kept up with it, so now you have people who know the new ways and people who know the old ways and various stages in between (and it's not like they didn't try ditching backward compatibility, but that didn't work out well either). Go has the luxury of starting 20 years later and being a lot less ambitious, but it'll happen to Go too in time.
- dragonwriter 3y agoIMO, its not “hilariously wrong” in Python. Note that as written the priority is that every use case has at least one obvious approach, and that a secondary priority is that there should be a unique obvious approach. People often seem, however, to misread it as “there should be only one possible way to perform any given task.” Which, yes, is hilariously false for Python, but also not what it says.
- bsder 3y agoYou're young enough to have never dealt with write-only Perl code ... Be glad.
- lelanthran 3y ago> You're young enough to have never dealt with write-only Perl code ... How young does one have to be for that to be true? As recently as 2017 I was employed at a place where there was a significant amount of perl code, as part of the build system (ugh) for the C code, and generating html (for some other system).
- imiric 3y agoI like Python, but most of the Zen has always been a meme, and not a guideline of design principles of either the language, or software written with it. Besides the one you mention, I also find the "Explicit is better than implicit" line to be against everything Python stands for. The language is chock full of implicit behavior, and strongly encourages writing implicit code. From the dynamically typed nature of the language itself, to being able to define dunder methods that change the behavior of comparison and arithmetic operators. I really like Go partly because of this. Not only does the language itself stictly follow the explicit over implicit and TOOWTDI principles, but it encourages or even enforces them on the programmer.
- vonwoodson 3y agoIt is absolutely not a meme, it's [PEP 20](https://peps.python.org/pep-0020/ https://peps.python.org/pep-0020/). Just because some people don't take it seriously, it's definitely a part of the language's soul.
- danShumway 3y agoI'm from the outside looking in so don't take me too seriously because I tried Python and bounced off of it; there's very likely elegant parts of the language that I never really internalized because I didn't spend enough time working with it. But speaking as someone who tried Python because I agree with principles like "have one right way to do things" and "be explicit", my initial impression working with language is that much like real souls, Python's soul is metaphysical, unobservable, and doesn't seem to interact much with the physical world in an observable way ;) If I had to list some of my main criticisms of Python it would be that the language seems to have way too much implicit behavior and seems to have way too many ways of doing everything. I'm going to say something heretical, but it was weirdly enough early Javascript that I found to be a lot more consistent and explicit[0]. Type casting was a disaster of course, dates and the standard APIs were a complete mess, but beyond that it was rare for me to look at Javascript code and think "I have no idea what the heck that is doing." But it happened all the time in Python, it took me a while to get used to things and I still feel generally less capable in Python than I do in other languages that I've spent less time working with. There's so many little syntactic tricks in the language that are... convenient, but I resent having to memorize all of them. [0]: Until it started messing around with classes and const and Symbols and crap -- the language is probably much harder to learn now than it used to be in the past, but I don't know because I'm disconnected from new users now. But certainly having 3 ways to declare a variable now probably doesn't help new users. ---- As an example, just this weekend I tried to convert a Python codebase from 2.0 to 3.0 and was immediately hit by needing to resolve implicit casting rules about integers, buffers, and strings that were all different now. Python has this weird thing where sometimes it does implicit casting behind the scenes and sometimes it doesn't? There's probably a rule about it, but it's never been explained to me. So then I wanted to figure out the best way to handle converting a string of hex values into a manageable format so I searched that up and got advised that I should use `struct.unpack` except to be careful because that would give me a tuple instead of a list and also would require me to pass in the length, so instead I should actually use `map(ord, s)`, which prints out something that certainly seems to look like a list, but is not subscriptable, which is not a thing that I knew that I needed to care about but apparently do because the program broke until I cast it back to a list. And probably what I should have done was list comprehension from the start? But it wasn't clear to me if I could do list comprehension on a string or not since I do know that strings in Python technically aren't lists, they're sequences, and anyway list comprehension was not what people were suggesting. And I know it's unfair because this is very beginner stuff in the language, but my immediate thought was, "oh right, Python. Of course when my debugger prints out something that looks like an array of values it might be one of 3 or 4 different types behind the scenes, all of which will error for subtly different reasons. It was silly of me not to see this coming." Again, fully aware that this is basic stuff that would completely go away with familiarity with the language, but like.. oh my goodness my kingdom for having one array type that just works everywhere and one iterable quality that supports the same manipulations everywhere no matter what the underlying type is. I'm trying to do quick scripts, if I cared about these distinctions and if I cared enough about performance to need multiple ways to have a list of values, I'd have written this in Rust or at least C# or some fully typed lower-level language. There doesn't need to be this many ways in a scripting language to say "I have an ordered collection of values." I'm not saying you're wrong, I suspect you're right. I suspect the underlying language is much more elegant than what I'm seeing. All I'm saying is just that the initial impressions of Python for people like me who are really inexperienced with the language are anything but the PEP 20 list -- the impressions are the opposite, it's exactly why I bounced off of Python so hard. And I don't think that's individuals doing something weird, that seems baked into the language? Individuals didn't give Python 4 different ways to represent a sequence of values. I don't think it's a few coders' fault that I'm constantly seeing syntax in Python where having the code look prettier seems to be the priority over making it understandable or explicit? Again, take it with a grain of salt, just... I don't know, I always laugh when I see the PEP 20 linked because it's so contrary to how I think the language looks to new users. I could compare this to something like Lisp, which I am also extremely inexperienced with and extremely bad at writing, but when people talk about Lisp having simple rules, I think, "yeah, I see that. I see the system that you're talking about and I see the consistency you're talking about." With Python I just don't see it, the initial impression makes it feel like a language written by graphic designers trying to create something that's pretty rather than systemic.
- felipetrz 3y agoThere is always one obvious way to do things in Python, but it happens that what's obvious varies from person to person.
- fuzztester 3y agoLike those various personal subsets of C++ :)
- chaxor 3y agoFar faaaar better with respect to this than R though at least.
- nwallin 3y agoYeah. It is now. It didn't used to be though. People would wax poetically about how pythonic some codebase was and sing the praises of idiomatic python. There was an ideological war between Python ("there should be one--and preferably only one--obvious way to do it") and Perl. ("there's more than one way to do it" or TIMTOWTDI, pronounced "Tim Toady") Generators and comprehensions and decorators and `functools` are all relatively new.
- harpiaharpyja 3y agoI feel like the entire industry has adopted Python's approach here, so probably Python doesn't stand out on this point as much as it did in the early days. Compare Python to C/C++, where even just getting a working binary from source is fraught with many competing tools. Or boost vs std and whatnot. Others have already pointed out the contrast with Perl.
- cdchn 3y agoNot really. For the core language this applies. This does not extend to 3rd party libraries, obviously, since anyone is free to reproduce whatever someone else already doing better, if they want.
- throwawaymaths 3y agoThat was then. Python does much much less explicitly anymore these days, either.
- exhuma 3y agoThis held up much better in the earlier days of Python. Sooner or later every sufficiently popular programming language is confronted with the dilemma of either breaking backwards compatibility and/or adding "alternative ways to do things" Pathlib is an interesting one. It even has a correspondence table [1]. The introduction of pathlib made sense because it is just much nicer to use. But you couldn't drop the equivalent functionality in the "os" module for backwards compatibility. It's just far too widely used. The is no magic bullet for this one. Either you accept introducing duplication in your language or you go through a hard change (f.ex. the Python 2 to 3 change). The softest way to migrate might be to flag functionality as deprecated and give users a fairly long time (talking years) before dropping it. But no matter how much time you give the users there will be users who won't change until it's too late. So there really isn't a winning path for this one. [1]: https://docs.python.org/3/library/pathlib.html#correspondence-to-tools-in-the-os-module https://docs.python.org/3/library/pathlib.html#correspondenc...
- michaelcampbell 3y agoI like also the idea of explicit>implicit, but then you see Django. I hate significant whitespace though. I can work with it, I get it, I still don't like it.
- sacado2 3y agoBack then (in 2004) the most popular programming languages were PHP, Perl, C++ and Java. Java was pretty focused (and even then, there was the distinction between int and Integer, between []int and ArrayList, etc.) but C++ and (especially) Perl were driving people crazy because there were thousands of ways to do the same thing. And nobody had any respect for PHP's design so let's not even talk about that one.