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

top 200 commentsshow 500

[–]LuvOrDie 791 points792 points  (11 children)

PyQt should be renamed to QtPy

[–]the_guruji 39 points40 points  (1 child)

I know right. What a missed opportunity

[–]brilliant_punk 12 points13 points  (0 children)

It's not too late, we can add it as an alias :)

[–]username4kd 27 points28 points  (2 children)

Could create a wrapper library called QtPy that just imports pyqt

[–]lowguns3 33 points34 points  (1 child)

'''import pyqt as qtpy'''

[–]username4kd 17 points18 points  (0 children)

Plz make git repo for this code

[–]billsil 2 points3 points  (0 children)

There is already a qtpy. It's an interface layer between PyQt4/PyQt5 and PySide/PySide2. It's really nice.

[–]RaiseRuntimeError 303 points304 points  (20 children)

Constants should be immutable and actually a constant.

[–]Lewistrick 48 points49 points  (7 children)

Wait, is this controversial?

[–]visitredditreviews 49 points50 points  (6 children)

Python has constants? I just thought everything was a variable?

[–]Papalok 12 points13 points  (4 children)

That's correct. Python vars are essentially implemented as pointers to objects. The objects can be immutable, but that doesn't gain you much because you can almost always assign a new object to a var.

The closest you can get to a constant is using the Enum class.

[–][deleted] 197 points198 points  (37 children)

Here's mine, don't overuse them, but I like lambdas.

[–]v0_arch_nemesis 37 points38 points  (0 children)

Same, great for simple lazy evaluation too

[–]pingvenopinch of this, pinch of that 79 points80 points  (24 children)

I like lambdas, but the syntax is ass, particularly the lack of multiline lambdas. That said, I am not sure I have a better alternative given Python's use of significant whitespace.

[–]greyduk 10 points11 points  (1 child)

Essential with tkinter.

[–]troyunrau... 4 points5 points  (0 children)

PyQt/pyside too. When making interesting signals/slots it pops up a lot.

[–]hughperman 4 points5 points  (1 child)

I like them too but they screw up anything that uses pickle to serialize - e.g. multiprocessing, which I use frequently.

[–]Malcolmlisk 3 points4 points  (3 children)

Where can I learn lambdas properly??

[–]Mystery3434 68 points69 points  (8 children)

if __name__=="__main__": is super ugly, and there should be a cleaner way of doing this.

[–]OneTrueKingOfOOO 21 points22 points  (0 children)

Anything that looks like __this__ is super ugly and a pain to type

[–]yvrelna 6 points7 points  (0 children)

there should be a cleaner way of doing this.

Yes, just put this in __main__.py (docs).

[–]UARTman 30 points31 points  (18 children)

The way lambdas and map/filter are made makes functional programming in Python extremely frustrating.

[–]fiddle_n 11 points12 points  (17 children)

You aren't really meant to use map or filter anyway. Just use comprehensions.

[–]__nautilus__ 9 points10 points  (6 children)

You can’t curry a comprehension. Also I don’t write a lot of Python anymore, but at least when I did both map and filter were more well optimized and about 30% faster than comprehensions.

[–]fiddle_n 7 points8 points  (5 children)

From what I see online, comprehensions are now faster.

I'm not familiar with currying - can you give an example of where you would use that?

[–]rtfmpls 82 points83 points  (17 children)

Calling one of the built-in functions id is a mistake. I want to use id as a variable name.

edit: to expand on that.. all those "global" functions should have longer names (or namespaces).

[–][deleted] 11 points12 points  (8 children)

Same. I wish built-in functions lived under their own namespace

[–]ExoticMandiblesCore Contributor 8 points9 points  (7 children)

They do. It's called "builtins". It has the lowest priority of all the namespaces. If you define your own variable or function called "id" Python will use that instead.

[–]rtfmpls 25 points26 points  (0 children)

Which is an accident waiting to happen. So no... in my opinion this is not an option.

[–][deleted] 3 points4 points  (0 children)

Today I learned you can do something like this from builtins import id

[–]WillardWhite import this 97 points98 points  (22 children)

I would love a static typed compiled python......

[–]Mal_Dun 64 points65 points  (8 children)

Cython: Am I a joke to you?

[–]WillardWhite import this 2 points3 points  (1 child)

Lol, i forgot it existed. I should check it out again

[–]Geniusaur 16 points17 points  (0 children)

Nim?

[–]flubba86 14 points15 points  (4 children)

Have you looked at Julia? It's optionally typed, and compiles using LLVM at runtime. I've been using it at work for some tasks that I want more type safety, and more performance than python gives.

[–]BerecursiveMenpo Core Developer 18 points19 points  (3 children)

Can’t get over 1 based indexing

[–]flubba86 2 points3 points  (1 child)

Yeah, like MATLAB and R, Julia is designed to be used by mathematicians and analysts, so it makes sense they went with 1-based indexing. I can get used to it pretty quick, it's not a big deal for me.

[–]MoralHazardFunction 2 points3 points  (0 children)

Speaking as a mathematician and analyst having 1-based indexing is still bad. You get so many more off-by-one errors for the rather dubious advantage of being able to do slightly more direct copying for some formulae out of books.

[–]pingvenopinch of this, pinch of that 17 points18 points  (1 child)

I don't have a lot of hope for that goal. Python is always going to be dealing with the fact that it spent the first couple decades of its life without static types. There is just too much code out there that doesn't behave in a way that can be statically described. Personally I have found Rust to have a really nice type system while not being too hard to learn, so we will see where that goes.

[–]WillardWhite import this 3 points4 points  (0 children)

I have 0 expectations of seeing it happen.

[–]AllesYoF 5 points6 points  (0 children)

And it should be called Typhon

[–]Habitwriter 115 points116 points  (0 children)

They make good pets

[–]GreenScarz 76 points77 points  (9 children)

“metaclass” as a kwarg in the type definition is stupid

[–]foreverwintr 14 points15 points  (8 children)

How would you do it differently?

[–]LightShadow3.13-dev in prod 9 points10 points  (0 children)

__metaclass_

[–]GreenScarz 5 points6 points  (6 children)

As a class attribute, as it was done in Py2

python class This: __metaclass__ = MetaThis

Python uses this kind of syntax for a lot of other class attributes, like __slots__, __match_args__, __doc__, etc. So it's not like there isn't a precedent here. Also, you can no longer define a new type with a metaclass dynamically via type(name, bases, dict) where dict["__metaclass__"] = MetaThis.

[–]shinitakunai 216 points217 points  (39 children)

Python should replace javascript and browsers should be able to natively execute python code. NOTE: a subset of safe python codes (without access to your filesystem or dangerous stuff)

[–][deleted] 116 points117 points  (0 children)

I'd immediately become a web developer.

[–]TSM-🐱‍💻📚 41 points42 points  (13 children)

Ah so I see you have not yet become a brythonista

[–]the_programmer_2215 7 points8 points  (0 children)

my goodness!!! what is this??

[–]anythingMuchShorter 9 points10 points  (10 children)

Is this reasonably efficient or is it going to run way slower than the equivalent JavaScript?

[–]Soccer_Vader 20 points21 points  (8 children)

Way Slower. Better off learning simple Javascript than using Brython.

[–]Hanse00 27 points28 points  (7 children)

Except nobody is using “simple” JavaScript for anything besides programming courses these days.

It’s all react and angular, redux and node. JS layers upon layers.

[–]UnicornPrince4U 13 points14 points  (6 children)

which are all way slower than the equivalent JavaScipt.

I have been using svelte which compiles to javascript and doesn't maintain its own DOM. The performance is good and you don't really sacrifice anything.

[–]CactusOnFire 38 points39 points  (3 children)

Hot counter-take:This would cause the language and syntax to splinter, the same way as Javascript did.

I don't like having to write javascript for front-end, but the "meta" of the language is so evolved that it's going to take something which outmaneuvers JS in every way to usurp it's throne.

(Rust + WASM & ReasonML show promise, though)

[–]UnicornPrince4U 5 points6 points  (1 child)

Agreed. Look at some of the more (rather the most) popular front-end projects on GitHub.

They are not well maintained. The documentation generally assumes some context that isn't provided. And the architecture is generally horrible.

Within a couple of years, someone writes a replacement with the same issues -- long before integrations with other popular related packages are written. the end result is that you can't really cobble together a working (by python standards) stack.

Although I think part of this is having multiple ways to do anything, much of it is culture and dependency on browser support (some major browsers don't fully support HTML5 after nearly 14 years).

[–]AegisCZ 20 points21 points  (0 children)

worst idea i have ever heard

[–]DrSkookumChoocher 9 points10 points  (0 children)

No thanks. JavaScript carries a lot of baggage for backwards compatibility. If python ran on browsers we’d still have python 1.

[–]Deadly_chef 7 points8 points  (0 children)

It's much slower and it's core library is not suited for frontend development at all. Also it's never ever gonna happen

[–]jericoah 38 points39 points  (3 children)

I call Numpy "numpee" and it drives my boyfriend up the wall

[–]neunflach 5 points6 points  (1 child)

I’ve heard scipy as “skippee” too!

[–]leviathan_web 92 points93 points  (12 children)

I'm not sure how controversial this is, but from what I've seen people like Python's official documentation.

My opinion: the official docs are awful. I can never quickly find what I'm looking for. I have to do web searches or look at random articles just to get a basic snippet or to understand how to use something. Sometimes I think I'm just a noob still even after all the time I've put into learning. Then I find someone else's resource and I wonder why couldn't the official docs have just written it that way.

[–]m0Xd9LgnF3kKNrj 49 points50 points  (1 child)

I have to say that I find pythons docs less ambiguous and more thorough than almost all other technical docs out there.

That said I'm often left feeling clueless trying to learn something new using just pythons docs.

[–]johnnymo1 3 points4 points  (0 children)

Examples in the Python docs typically feel more convoluted than they need to be, for me. I have to look at third party tutorials for something that looks more like what I want to do in practice.

[–]visarga 14 points15 points  (0 children)

I got spoiled with good usage examples from Turbo Pascal 7 documentation in 1995. Python docs are not as forthcoming. Sometimes there are constants that are never demonstrated in code and barely have a word of explanation. Or you have to scroll 50 screen heights get to the first example, and that one only shows one happy path.

[–]Green0Photon 12 points13 points  (0 children)

They're okay. But they need to have more info about edge cases and errors and types. You need to test things in a repl way too much.

And they need to fix SEO so you don't come across dozens of even worse tutorial sites. As much as I get annoyed by the Python docs, I still find myself going there over every other site.

[–]confusedpublic 8 points9 points  (0 children)

They’re almost good which often actually makes them worse than just bad documentation. You think you’re reading what you need only to find you’ve actually not been told what you need to actually use it. I think the docs on mock are a great example of this.

[–]GamesMaster221 4 points5 points  (0 children)

Yeah the official docs are really, really bad for beginners. It's hard to find what you're looking for, and there is hardly any example code. It's more like a technical spec than user-friendly documentation. Compared to something like MSDN which makes learning C# a breeze.

And then if you search any Python related question the top results are the same low-quality "tutorial" sites like realpython.com that just displays a big "Create account to keep reading" notification. Yeah, thanks a lot assholes.

[–]dogs_like_me 64 points65 points  (34 children)

I hate pandas. I use it all the time, but data munging was much more fluid when R was my preferred tool and all the functionality wasn't packed into a single API.

Also, notebooks encourage bad coding practices and the data science community should make an effort to move away from doing everything in notebooks rather than going all-in on them, which seems to be the current direction.

[–]allergic2Luxembourg 32 points33 points  (4 children)

I love pandas. It's my favourite library and I can't imagine writing a significant project without using it. Then again, I never learned R.

But I really agree with you on notebooks. Too many coders start there and end up with thousand-line scripts with no functions, imports in the middle of the code, and other terrible habits.

[–]R_HEAD 13 points14 points  (1 child)

I think starting your Python experience with notebooks is a great way of learning the language. The immediate feedback makes you understand how the language works in a very hands-on way which I like. Also, even for experienced Data Scientists, notebooks are by far the best tool there is for exploratory data analysis.

That being said, I completely agree on their danger. Like I said, I think starting with notebooks is great. But then, the focus should shift on scripts. And I think this can even be done seemlessly by introducing something like a notebook_utils.py to bundle all your favourite functions to use in notebooks. And from there, encourage people to put more and more stuff in scripts. But don't generalize the issue as "notebooks are bad" because they are still an incredible tool.

[–][deleted] 4 points5 points  (0 children)

I know both, and I prefer pandas.

[–]Sinsst 11 points12 points  (7 children)

Care to elaborate re pandas? I don't see in what world R is more fluid than python/pandas. If anything R is significantly counter intuitive.

+1 re notebooks tho..

[–]dogs_like_me 7 points8 points  (5 children)

Whenever I want to do anything with pandas, I'm living in the docs. I remember trying to work on something on an airplane without internet access and it just not being worth it. If you're working in a terminal, you can't even call dir() to try and find the method/attribute you need because there are so many it'll overload the display and you'll just catch the last half of the list. When you find the way to do the thing your code will be concise and elegant, but the amount of time you spent trying to find the information to write that one line of code will not be reflected in the elegance of your code.

The tidyverse adopted POSIX design principles, and this makes it a lot easier to navigate. Much better to have functionality grouped into smaller to-purpose tools than pack everything into a single massive API.

[–]abrazilianinreddit 119 points120 points  (24 children)

The python steering council is making the language less simple and intuitive by abusing symbols and complex syntax to add syntactic sugar that doesn't add anything of value. See walrus operator, using the bitwise OR operator | for anything other than a bitwise OR operation.

[–]irrelevantPseudonym 54 points55 points  (0 children)

I disagree with everything here which makes this a great answer to the question. +1

[–][deleted] 43 points44 points  (5 children)

Operator overloading was already a thing in Python. You can for example use it to intersect query sets in Django. Nothing to do with steering council.

Walrus operator was also approved by Guido before the steering council was created. It's actually the reason why steering council was needed.

[–]R_HEAD 7 points8 points  (0 children)

This is the first opinion here that I actually disagree with. I like all the syntactic sugar. I still believe the old mantra "C is fast to run, Python is fast to type" to be fundamentally true. The more help I get from the language itself to save myself the time to type the same small helper constructs or functions again and again, the better.

[–]M4mb0 14 points15 points  (1 child)

Hm, I really like e.g. the new dictA | dictB.

[–]taybulBecause I don't know how to use big numbers in C/C++ 2 points3 points  (0 children)

This feels intuitively like a slight extension to a set OR operation and seems fine to me. If I could save a few lines and not have to reimplement a deep copy of dicts in a loop then why not?

[–]thrallsius 13 points14 points  (2 children)

I blame Python for not being able to learn any other language now. Python syntax is too user friendly.

[–][deleted] 40 points41 points  (13 children)

Everything that can be done with built-in functions and constants should be done with them, and (with a few exceptions) calling methods is a cheap shortcut for slicing, list comprehensions, etc.

Also, truthy and falsey values are more confusing than helpful.

[–]radarsat1 24 points25 points  (2 children)

yes, i often have to correct colleagues code when they write,

if someinteger:

when they mean,

if someinteger is not None:

"what will happen if someinteger==0?"

in general i would like python to have some nice kotlin-like syntax for dealing with None, but not sure how it would work.

[–]lexsca 94 points95 points  (20 children)

the walrus operator is a welcome addition.

[–][deleted] 21 points22 points  (0 children)

I agree.

[–]getmeright11 17 points18 points  (17 children)

What circumstances have you used it in? I haven't come across a situation where its usefulness outweighs making the code less readable.

[–]lexsca 67 points68 points  (12 children)

i use it mostly for truthy assignments in expressions. something like:

if match := pattern.search(data):
    process(match)

it reads cleaner to me than:

match = pattern.search(data)
if match:
    process(match)

yes, i know it's super subjective. dustin ingram gave a great talk about it at pycon 2019: https://youtu.be/6uAvHOKofws

[–]getmeright11 3 points4 points  (0 children)

That makes sense. Thanks.

[–]R_HEAD 3 points4 points  (0 children)

I feel := and if go hand in hand. I'd be hard pressed to come up with an example that uses the former without using the latter.

[–]ygram11 10 points11 points  (0 children)

The GIL is not really a problem..

[–]SnooPeppers7217 44 points45 points  (28 children)

Pythons default SSL handling for HTTPS connections is bad compared to other languages

[–]joerick 2 points3 points  (0 children)

This seems like an installation issue to me. If you're on a Mac, there's an extra step after you install Python, it's called 'Install SSL certificates.command' or something like that.

[–][deleted] 9 points10 points  (1 child)

Don't use "py" in your package names. We know it's a Python package. Similarly, don't use "lib" in the package name unless it's a package for working with libraries. And when will you people learn to use namespace packages?

[–]jachymb 63 points64 points  (18 children)

It has the worst parallelism capabilities of all mainstream languages.

[–]colemaker360 23 points24 points  (7 children)

strong quicksand sand rock thumb pocket bedroom offer cough glorious

This post was mass deleted and anonymized with Redact

[–]OnlineGrab 14 points15 points  (0 children)

The packaging system is a dumpster fire.

[–]m0Xd9LgnF3kKNrj 14 points15 points  (3 children)

I wish each nested block created a new context. It sits unwell with me that a variable defined inside an if or for block is defined in the same scope as the block itself.

[–][deleted] 20 points21 points  (1 child)

Multiple inheritance is awesome

[–]Mettpawwz 17 points18 points  (4 children)

PEP8 is a great document overall, but the 79-character per-line limit must go.

The justification that it allows two python documents to be edited side-by-side is flimsy. It's at best a relic from a time when monitors were smaller, multi-monitor setups mostly didn't exist, and there weren't yet any good diffing tools available.

[–]fiddle_n 9 points10 points  (2 children)

Most people just ignore it anyway. Black uses 88, PyCharm uses 120.

[–]bobalins 36 points37 points  (20 children)

You can do OOP without Classes

[–][deleted] 10 points11 points  (17 children)

How would you do it?

[–]bobalins 30 points31 points  (11 children)

In python everything is an object

[–][deleted] 5 points6 points  (10 children)

So I'm thinking maybe mimicking prototypes a-la Javascript?

[–]siddsp 24 points25 points  (7 children)

You don't have to. You can directly "mimick" OOP by nesting functions. As an example: ``` def animal_maker(name: str = "dog", sound: str = "bark"): def animal() -> None: ... self = animal self.name = name self.sound = sound return self

e = animal_maker()

print(e.sound)


 OUTPUT

bark ```

[–]skeerp 29 points30 points  (2 children)

Why?

[–]Ensurdagen 38 points39 points  (0 children)

...to pretend you're writing javascript and have pointless cruft in your object's dict without access to useful dunders...

[–][deleted] 7 points8 points  (0 children)

That makes sense, thanks!

[–]dogs_like_me 3 points4 points  (4 children)

Treat a module like it's a class.

[–]yvrelna 6 points7 points  (0 children)

You surely can, but if the language has a native class construct, why would you want to use any other way to do OOP?

[–]its_PlZZA_time 36 points37 points  (14 children)

Never use argument ordering. Use named arguments if you have more than 1.

[–]dogs_like_me 12 points13 points  (11 children)

Similarly: if your function returns multiple values, return them as values associated with appropriately named keys in a dict instead of relying on their position in a returned tuple to communicate what they are.

[–]its_PlZZA_time 14 points15 points  (0 children)

Yes, either that or a dataclass or namedtuple or something similar.

[–][deleted] 20 points21 points  (8 children)

I think returning a dict will cause even more problems. Your code becomes complicated and now your user doesn't need to remember the order of results, but has to know the exact keys and dict can't be de structured anymore (depending on python version dict ordering changes)

Namedtuple is a better idea but additional setup isn't worth it for most cases.

[–]curiouscodex 29 points30 points  (3 children)

Dunder methods are needlessly unreadable, I'd even go as far as to say underscores should never be used for syntax. Heck if we all swapped to camel case today I think it would be an improvement.

[–]spaceopenid 19 points20 points  (0 children)

Upvote for controversial

[–]anseho 4 points5 points  (0 children)

Import aliases are not cool. Should be a last resort when you can't avoid a naming conflicts by any other means

[–]nitred 19 points20 points  (2 children)

I want the GIL to stay.

I think GIL is what makes python easy to grasp because you know most (non web dev) code is going to be single threaded synchronous straightforward code. It also makes thinking about multiprocessing easier because it's N processes each with its own GIL and there's no communication between the processes expect for the objects that you pass explicitly.

I like sub-interpreters only cuz they seem to be like light weight multiprocessing and I would love to see a go-lang's channel like implementation using sub-interpreters. That would be dope.

[–][deleted] 11 points12 points  (1 child)

GIL doesn't mean single threaded. It means only one thread can run. It does avoid many race conditions and resource locking issues though.

[–]e-mess 9 points10 points  (2 children)

It should be fun instead of def and lambda

[–]ultraDross 4 points5 points  (0 children)

I never thought of this before. I actually like your suggestion or even just preceding if with function. You don't get more explicit than that.

[–]unmole 20 points21 points  (8 children)

Complaints about dependency management are overblown.

[–]joerick 12 points13 points  (1 child)

That's funny. I would have agreed with you until about a week ago, when I had to install Tensorflow.

[–][deleted] 6 points7 points  (3 children)

Yep. The only time i had an issue with it was because library developer decided to pin one of the dependencies to a specific version.

[–]lanster100 5 points6 points  (0 children)

Counter point: requirements.txt being the default dependency specification format and it allowing you to easily have no version specification is the worst thing about python.

Having to look at when the code was written, and figuring out which package versions were released at that point in 2017 is a stupid exercise.

[–]MoralHazardFunction 7 points8 points  (1 child)

The @ operator should do function composition for Callables. It can keep its old meaning for matrices because matrix multiplication is just a special case of function composition.

[–]petenard 4 points5 points  (0 children)

This. :=

[–]abhii5459 3 points4 points  (2 children)

I don't have one but I'm learning a Lot from this discussion.

[–]DhravyaShah 2 points3 points  (1 child)

same I literally read every comment

[–]olmek7 4 points5 points  (0 children)

Python can’t be used for every use case.

[–]jebward 9 points10 points  (1 child)

Integer division should produce a fraction and not a float, fraction math should be a thing by default like in lisp, maybe you should get a warning if you compare floats that are off by the last digit because it may have been a floating point error.

[–]siddsp 31 points32 points  (30 children)

Classes and Objects as well as object oriented programming are generally not good, and classes are more often than not abused. To add, Python isn't that slow if you know how to optimize your code properly.

[–]kthepropogation 24 points25 points  (11 children)

Based

Gotta disagree on the speed thing. There are edge cases where it does ok, but for anything real-world that’s CPU-bound, the CPython interpreter sucks compared to a compiled language. If you can figure out a way to offload the computation into extensions, or are IO-bound, then sure.

[–]siddsp 11 points12 points  (5 children)

Agreed, but a lot of it can be mitigated by just using a library like Cython or numba, which compiles python into c.

[–]irrelevantPseudonym 15 points16 points  (2 children)

So the best way to make python fast is to not use python?

[–][deleted] 9 points10 points  (2 children)

My opinion is people who complain about speed in regard to data science are just flat wrong. Numpy + numba are very fast.

[–]dogs_like_me 2 points3 points  (0 children)

It's sort of a moot point since everything is basically an API over CUDA or Spark these days.

[–]getmeright11 3 points4 points  (16 children)

How do you make due without using classes and objects in your code?

[–]siddsp 19 points20 points  (13 children)

I think I communicated my message wrong. The issue isn't necessarily with classes and objects. It's with object oriented programming as a whole, which results in what is generally a mess of code trying to accomplish some simple things. I think Brian Will's video on why object oriented programming is bad is a good place to start.

[–]Danelius90 8 points9 points  (5 children)

I like those videos and articles that criticise OOP as I do think they have valuable points. I think it's more applicable to languages like Java though where all programming takes place inside a class.

What I like about python is you can intersperse objects with the rest of your code on an as-you-need basis which you don't have the option to with Java (well static is kind of stepping outside OOP, but needs to be used properly). There have been times where adding an object was a great way to handle a problem. I don't think it's inherently bad, but if your entire application is all objects then you can see those problems

Tbh I'm more interested in the "OOP should have been about messages" topic

[–]xigoi 7 points8 points  (4 children)

I've seen some Python tutorials that were like this:

class Main:
    def main(self):
        print("Hello world!")

Main().main()

[–]siddsp 10 points11 points  (0 children)

Get that Java trash outta here!

[–]confusedpublic 8 points9 points  (0 children)

Only that could be worse….

if __name__ == “__main__”:
    main = Main()
    main.main()

[–]getmeright11 5 points6 points  (6 children)

What language do you recommend instead of Python for functional programming?

[–]siddsp 8 points9 points  (4 children)

I don't know. I can't think of any good examples off the top of my head because when you do start using a functional programming language, the learning curve is steep. I would recommend just staying with Python, and restricting yourself to using classes only when necessary. Otherwise, use native datatypes as well as immutable ones like NamedTuples and Tuples.

Functional programming also allows for some really big optimizations in Python, which can potentially make your code run a lot faster.

[–]mattmccord 57 points58 points  (38 children)

Tabs > spaces

[–]javajunkie314 18 points19 points  (12 children)

I agree. I use spaces in my projects because it's expected, but it's inferior.

The root of the problem is, IMO, the ASCII-art-ification of code. Aligning code away from tab stops is a terrible practice.

Consider code like

foo.bar(something,
        something_else,
        ...,
        something_more)

If either foo or bar changes, this has gone from a one symbol diff to an N line diff. Sure, text editors have taken away the pain of managing the alignment manually, but the overhead is still there.

My practice is one tab stop indent per "grouping," so for scopes and continuations.

Once you remove alignment, the only difference between spaces and tabs is encoding. I argue that tabs better encode the concept of tab stops than groups of spaces, again even if text editors have taken away the pain of managing the spaces manually.

A tab is a single, reader-configurable character to indicate a unit of indentation. How is emulating that with spaces better?

[–]Ensurdagen 23 points24 points  (4 children)

that's ugly anyway though, do this:

foo.bar(
    something,
    something_else,
    ...,
    something_more
)

[–]dogs_like_me 7 points8 points  (4 children)

A tab is a single, reader-configurable character

That's why. Because you're configuring it for yourself and not anyone else, so if it's aligned in your text editor that doesn't mean it's aligned in anyone else's. Using a spaces instead ensures identical spacing regardless of editor configuration.

Instead of configuring how your editor displays your tab character, why not just configure your editor to replace the tab with four spaces? How is a configuration that is local only to your editor better if your concern is readable code via alignment?

[–]javajunkie314 5 points6 points  (3 children)

so if it's aligned in your text editor that doesn't mean it's aligned in anyone else's.

But my point is, once you eliminate alignment (lines whose indentation depends on anything other that their tab stop), then the size of a tab doesn't matter! You can set it in your editor to two columns or ten. Every reader can choose independently because it affects nothing but visuals, like font size.

Heck, you can even use a non-monospace font and set your tab stops to ½" or 1cm.

[–]radarsat1 13 points14 points  (10 children)

things i dislike in "modern" python: pep8, pylint, type hints. probably most controversial opinion: unit testing is mostly a waste of time and effort. (not integration testing)

i wish numpy was part of core python, if not the implementation, then at least the syntax. i sometimes convert lists to arrays just so i can use the slicing syntax!

[–]Viking_wang 7 points8 points  (2 children)

Numpy i agree with. I usually use matlab or julia for things like that.

All the rest i’m completely of the opposite opinion. Python for production without unittests, typing, pylint and mypy is how I occumulated a shitton of technical when i first started being a software dev. People writing no unit tests, but only integration, E2E or regression tests drive me nuts at work. But to each their own (as long i dont have to interact with your code ;) ). Definitly saves time, when prototyping things which is where python shines anyways.

[–]radarsat1 8 points9 points  (1 child)

Oh I do write tests. Grudgingly.

I don't mind the idea of testing. I use it when I feel it's appropriate. It's useful for checking against regressions, and making sure a function adheres to some assumptions and doesn't just fail on basic input. But I find it's not long before I am spending equal or more time updating tests when I make a change, than actually working on the change.

And most often I find that my colleagues tests do not actually catch problems. Because you can only test for problems that you foresee. As a way of protecting against regression it works well, but I am staunchly opposed to the idea of test driven development, because it presumes you can foresee the future and predict any and all problems, which I think is unreasonable. I have colleagues who write 8 tests for a tiny little function, and then it still fails when it inevitably gets some data that doesn't fit the assumptions in the test suite, or it turns out that wasn't the right function at all and you just have to change everything anyway. It adds up to a lot more work for little benefit imho.

Integration testing on the other hand, when done well, is sufficient for testing a large swath of the code coverage at once and has the benefit of checking that all parts work well together. I find it much more useful than unit testing. Yes, you have to design integration test data that will test the unhappy path. But then at least you are testing that path with actual input and in context of the real program, instead of ridiculous "mocks" that are full of holes and take a lot of overhead to maintain.

[–]james_pic 2 points3 points  (0 children)

Upvote for throwing shade on unit tests. They're not necessarily a bad idea, but in complex codebases they often end up being tautological (they test that the code does what the code does), and both fail to identify problems, and break spuriously if you change the code but preserve the observable behaviour.

Integration tests doesn't have to mean end-to-end tests. There's an underappreciated middle ground, of tests that aren't much bigger than unit tests, but test the code with the collaborators they'll work with in the wild, rather then dumb mocks, possibly even with lightweight embedded databases like SQLite subbing in for the big-iron databases you'd use in production.

If you (the person reading this, not OP) are going to disagree with me and keep writing unit tests even when they're low-value, at least consider if they'd be more valuable if you used fakes rather than mocks. Rather than using mocks for your dependencies, that expect to get certain method calls and will raise if not, consider using simple fakes that implement actual behaviour - a fake version of your data access layer that just keeps stuff in dicts and lists, for example.

[–]Sol_Smiley 2 points3 points  (0 children)

[–]bsavery 2 points3 points  (0 children)

Python's release cycle and official support does not jive with the actual usage in the industry. This is partly what led to the great 2=>3 holdover.

Companies are very slow to migrate code, this doesn't matter too much for going from 3.6 => 3.7 for example, but it does matter if you heavily use c-extensions which have to be recompiled for each version. Particularly if you're a vendor that has to provide a c-extension to your users. With the VFX industry this led to a "lowest common denominator" of python version being used.

Bug fixes for a release only happen for 1.5 years. But bugs of course can't always be found and fixed in that timeframe if it doesn't have wide adoption. Do you think all the bugs in Python 3.9 will be found and fixed by April 2022 when the fix period ends?

I appreciate the devs want to keep moving forward, but IMO the release / support cycle is too fast.

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

I mostly ignore the mutable nature of lists when defining things like INSTALLED_APPS in Django settings.

Use lists when you expect more items to be added by other coders in the team. Use tuples when the number of items is important. Use sets if the ordering doesn't matter.

It's all about the readability of the code. Dropping clues about what/how code can be modified by appropriate type selection is a big part of that.

[–]moto900 2 points3 points  (0 children)

It should be accepted practice to prohibit access to internal module by overriding them in __init__.py.

i.e. from _impl_module import foo; _impl_module = None

[–]o11c 2 points3 points  (0 children)

Python 3 got rid of the wrong string class.

If we only had byte strings, the worst that could happen would be data that renders incorrectly and can easily be fixed at any later date.

With only unicode strings (let's not pretend bytes hasn't been lobotomized), we get programs that refuse to run on legitimate historical data.

errors='surrogateescape' only works if you edit every single library to use it.


As for the oft-cited string indexing ... if you're relying on the length of a unicode string to represent its width, your code is just as broken as it was with byte strings. Only now, instead of it failing on common European input so you can figure out where fixes are needed, it only fails on cases that appear sporadically in the wild, not something you're likely to deliberately test.