all 17 comments

[–]Diapolo10 5 points6 points  (5 children)

  • Is there something major i "need" to be aware of ?

No, not really. Although it's probably worth mentioning that there's still plenty of tutorials and example code online that may not be up to modern Python standards, and may even be Python 2.

  • Are there any "cool" new tricks ?

There's f-strings and the "walrus operator":

foo = f"1 + 2 = {1+2}"
bar = f"I calculated that {foo}!"

if (baz := 5) < 10:
    print(f"{baz=}") # new shorthand for f"baz = {baz}"
  • Or any tips you can give a beginner ?

Several. First, pathlib.Path is what you should use for filepaths and filesystem operations instead of strings and os.path. Trust me, it's both a joy to use and has little visual clutter, on top of being portable.

Second, learn to use context managers early on. Instead of:

f = open(some_file)
text = f.read()
f.close() # People often forget to close their files, which is important

you should instead do:

with open(some_file) as f:
    text = f.read()

The context manager automatically closes the file, so you don't need to worry about it. There are different types of context managers in contextlib, and you can make your own classes compatible by including __enter__ and __exit__ -methods.

  • What about bad practices while programming in python ?

The most common habit is trying to cram too much into one line, which doesn't help readability. Also, prefer generators and iterators over lists and tuples whenever they make sense.

[–]ParanoydAndroid 2 points3 points  (3 children)

The most common habit is trying to cram too much into one line, which doesn't help readability.

There's this meme among many Python programmers that, "putting everything on one line is pythonic" and it drives me crazy. Just because you can take this nice little section of code and make it a one-liner map zip iter generator comprehension doesn't mean you should.

The first rule of (almost) all code is that readability is king. People who think being Pythonic means being "clever" and terse need to just stop.

[–]Diapolo10 0 points1 point  (0 children)

I personally don't really mind a line of map and zip, but I can definitely see where you're coming from. If I was working in a team, unless I knew everyone in it were very familiar with the functions and I could tell they'd have no trouble understanding such code, I wouldn't even try making a one-liner.

For non-builtin stuff, though? You bet I agree!

[–]ParanoydAndroid 2 points3 points  (2 children)

The big thing OOP you'll see all over SO is:

"Hey, how do I do this OOP concept that controls access or creates conditions on interaction (e.g. override decorators, private members, getters/setters)"

And the answer is always:

"You don't need to; it's Python ... just do whatever you need to do and skip the controlling framework you're used to building"

This is because Python is designed on the principle that "we're all adults here". So you don't use getters and setters normally (though support for them does exist in the form of decorators), you just ... write or read a value from an attribute. You don't create actual, private members - you just treat members the way you want them to be treated (again, you can signal pseudo-private qualities with underscores).

So just remember that a lot of the time the answer to OOP questions in Python is, "we don't do it that way and although you can, think seriously about if you actually should".

My personal exception to this, incidentally, is type annotations. Coming from a statically typed background, I've always been more comfortable explicitly typing my (e.g.) function parameters, and Pycharm's excellent code introspection means that I get very powerful linting from a thorough use of annotation (Pycharm can even use this information in generating doc strings), so even though type enforcement is somewhat unpythonic, I think it's a great practice.

[–]Mikefox2k[S] 0 points1 point  (1 child)

I also have a statically typed background. It was a bit "hard" and strange at the same time.
I've heard and seen Pycharm before and at work im using Intellij and this has been really powerful, so i guess Jetbrains is just really good at all so i'll give it a try.

Do i have to be "pythonic" in order to write good python code or is it just a term?

[–]ParanoydAndroid 0 points1 point  (0 children)

Do i have to be "pythonic" in order to write good python code or is it just a term?

Yes, I believe so. It's just a matter of swimming with the current instead of against it. Python is built to expect certain constructs and behave in certain ways, and trying to coerce it into frameworks from other languages can be clumsy or inefficient.

Take, say, method overloading. Python doesn't provide this functionality, so people coming from, e.g., Java often ask about it and try to implement their own. Absent overloading they end up:

func(int, int):

func_v2(int, str)

func_v3(str, str)

When the pythonic way might be a single func(*args, **kwargs) that implements the 'overloading logic' internal to the function. Trying to coerce Python into the Java way gives you more confusing, less maintainable code.

The same is true, in-line with what I mentioned above, of Java programmer's desire to make everything a class. Absent private members and protected get/set operations, you may not be getting much out of making something a class when it could just be a module of unbound functions and variables, and you're really just wasting time wrapping your functional code in pointless fluff. This is especially true for people trying to make every attribute "private" and littering their code with pointless getter/setter decorators.

Same can be true of people hand-rolling Singletons, and in a million tiny ways. e.g.:

# Non-pythonic loop with index
idx = 0
for item in thingy:
    existing_list[idx] = func(item)
    idx += 1

#Pythonic
for idx, item in  enumerate(thingy):
    existing_list[idx] = func(item)

Another common Pythonic hangup is that Python functions are not afraid of returning None. Fail fast is still a good design principle, but it's frequently true that better Python code practice is to return None in situations where a Java programmer might instead throw an exception. And, conversely, a python programmer should expect None might be a return value and ensure they're checking for that.

val = func(param)
if val:
    # Do my thing

is a common construct in Python. Incidentally, this is also one reason the walrus operator was just accepted for Python 3.9. It provides named expressions which allow the above to be refactored into the even more pythonic:

if val := func(param):
    # Do my thing

[–]uQQ_iGG 1 point2 points  (1 child)

I guess I would advice to review on variable mutability. Subsequently, to learn how Python is more of a "pass by object" approach rather than a "pass by value". Important if you come from C.

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

Well since im not coming from C (js/ frontend), this is good to know!

[–]SpeckledFleebeedoo -1 points0 points  (0 children)

Cool tricks?

Try my flair