3 Bad Python Habits To Avoid

Поділитися
Вставка
  • Опубліковано 5 чер 2024
  • Here are 3 bad Python habits I see a lot of people on the internet doing.
    ▶ Become job-ready with Python:
    www.indently.io
    ▶ Follow me on Instagram:
    / indentlyreels
    00:00 - Learning Python made simple
    00:05 - Intro
    00:12 - Bad habit #1
    02:57 - Bad habit #2
    07:01 - Bad habit #3
    10:20 - Do you have any bad habits?

КОМЕНТАРІ • 143

  • @Indently
    @Indently  3 місяці тому +21

    Sorry about that noise in the background! It was freezing in my room so for the first time in my life I turned on the radiator closest to my desk, and when I took off my noise cancelling headphones I realised it was pretty loud.

    • @rishiraj2548
      @rishiraj2548 3 місяці тому +2

      👍

    • @Whatthetrash
      @Whatthetrash 3 місяці тому +1

      No worries. Didn't even hear it! :)

    • @StYxXx
      @StYxXx 3 місяці тому

      Didn't hear anything. Should check my ears...

  • @Kommentierer
    @Kommentierer 3 місяці тому +145

    With a bare except block, you are also catching KeyboardInterrupt, something you definitely don't want in a console program.

    • @Indently
      @Indently  3 місяці тому +27

      Beautiful addition, I didn't even think about that.

    • @schwingedeshaehers
      @schwingedeshaehers 3 місяці тому +2

      sometimes you want, but at least you should check for it specifically, if you catch all

    • @Pacvalham
      @Pacvalham 3 місяці тому +19

      Catching/excepting KeyboardInterrupt is one step in recreating Vim in Python.

    • @uuuummm9
      @uuuummm9 3 місяці тому +1

      Are you sure? The "input" call is outside of the try catch.

    • @schwingedeshaehers
      @schwingedeshaehers 3 місяці тому +1

      @@uuuummm9 you have to time it perfectly, probably

  • @mudi2000a
    @mudi2000a 3 місяці тому +20

    Tell this to the developers in my company that you should not display “something went wrong”, it has become a running joke already.

  • @shakapaker
    @shakapaker 2 місяці тому +5

    1. Use specific exceptions instead of a bare except block. Provide meaningful error messages in exceptions
    2. Avoid mutable default arguments in function definitions. Specify function argument types for clarity
    3. Use iterators for memory efficiency. Understand the memory implications of data structures
    Write intentional and efficient code. Always aim for code that's easy to read, maintain, and efficient. Don't settle for quick fixes or lazy practices - that can lead to bugs.

  • @benjaminelo3709
    @benjaminelo3709 2 місяці тому +5

    For tip 1 I wouldn’t recommend using exceptions for control flow.
    Instead check that the input is a number first, and then ask the user to in put a valid number.
    In more complex programs it is not clear when people extend your work that your program is actually expected to throw exceptions.

  • @ruidian8157
    @ruidian8157 3 місяці тому +21

    I think one of the bad habits that bites me the most is not using "def main():". Not using that means every variable that you defined is in global scope. Sometimes silly mistake happens, and you end up making a function doing not what it was meant to do.

    • @VinceKully
      @VinceKully 3 місяці тому +3

      It's not the lack of a `def main()`, it's due to not having the __name__ check.

    • @ruidian8157
      @ruidian8157 3 місяці тому +4

      @@VinceKully Actually no. Even with the “__name__” check, the variable will still be global in the current file. I once wrote a function and forgot to include one of the required variable as the parameter of the function. But the code works with no error since I have a global variable which coincidentally has the same name as the variable. This causes some bugs and cost me a few days to finally found it…

    • @callbettersaul
      @callbettersaul 3 місяці тому +2

      Can't believe I never thought about the global variable part. I've never done a mistake by using them in functions, but I sure am annoyed every time pycharm suggests those variables to me, when I'm making a function. This would also remove the global variable shadowing warnings. It's decided, I'm going to start using main function as well.

    • @knut-olaihelgesen3608
      @knut-olaihelgesen3608 Місяць тому

      I often use globals - often read only constants, and I've never in my 4 years of using python had a real reason to use the main()/__name__ snippet. Globals aren't evil, but use them carefully

  • @DuncanBooth
    @DuncanBooth 3 місяці тому +10

    Sorry but the argument `target: list[T] = None` is itself a bad habit. mypy will flag an error for this and you really should be using a tool like mypy to ensure your type annotations are correct. Either `target: list[T] | None = None` or `target: Optional[list[T]] = None` is needed for valid typing.

    • @Indently
      @Indently  3 місяці тому +5

      No need to be sorry, you absolutely caught me there. I use Mypy all the time and should have quickly run my code through it before making the video.
      Thanks for pointing it out :)

    • @mudi2000a
      @mudi2000a 3 місяці тому +4

      And then it has become an unreadable mess. I find it fascinating that if you use those type hints Python code looks worse than any statically typed language including c++.
      I do actually think they are a good idea especially for functions as they allow self documenting code but I think they are not well designed and create lots of clutter.

    • @DuncanBooth
      @DuncanBooth 3 місяці тому

      @@mudi2000a I don't think adding '| None' makes it unreadable but I used to use the implicit form before mypy started blocking it because it is shorter. Also I dislike that it permits you to actually pass None explicitly while the implicit form says the caller doesn't have to pass an argument but if they do it must be a list. Now to do it properly you have to start using `@override` with all the possible signatures which does quickly become unreadable.
      This is kind of a contrived example though, I can't think of many situations where I'd have a function with an optional list argument that modified it. If I want an optional list argument and won't be modifying it I'd use `whatever: Sequence[T] = ()` and allow them to pass list, tuple, dict, set, whatever they want. Likewise `Mapping` instead of `dict`.

    • @callbettersaul
      @callbettersaul 3 місяці тому +3

      Your beloved mypy is mistaken here. Python documentation literally says this about typing.Optional: "Note that this is not the same concept as an optional argument, which is one that has a default. An optional argument with a default does not require the Optional qualifier on its type annotation just because it is optional. On the other hand, if an explicit value of None is allowed, the use of Optional is appropriate, whether the argument is optional or not."
      Meaning that Optional is not appropriate here as None is not actually a permitted value and is immediately replaced with an actual value. I thought it was common sense.

    • @Indently
      @Indently  3 місяці тому +1

      But None is permitted, and the whole purpose of None is that it checks whether the user has inserted a list or not, that type annotation is appropriate.
      Not only is None permitted here, it's also literally the default value.
      I know you're quoting the docs, but the docs ( docs.python.org/3.12/library/typing.html#typing.Optional ) do not entirely line up with what you're trying to say.

  • @DogiMetal
    @DogiMetal 3 місяці тому

    Learned something new today❤❤ thank you!

  • @krzysiekkrzysiek9059
    @krzysiekkrzysiek9059 3 місяці тому

    That's why I subscribe to this channel. Short, simple and very useful tips.

  • @SusanAmberBruce
    @SusanAmberBruce 3 місяці тому +16

    My bad habit is I don't practice writing code often enough, even though for me python is just an interesting hobby I still find some that I'm looking on Google to remember simple examples.

    • @Indently
      @Indently  3 місяці тому +19

      There's nothing wrong with googling no matter how simple it may be, I can do everything from scratch, but sometimes googling reminds me we have built-in functionality for what I'm about to do.

    • @bhai431
      @bhai431 2 місяці тому +1

      ​@@Indently *Please Make New Video On Making Telegram Bot wich work 24×7 and please must share the Script/Codes otherwise its very very difficult for us*

  • @phdnk
    @phdnk 3 місяці тому +2

    The Habit 2 is actually a consequence of the bad Python language design decision.

  • @somnvm37
    @somnvm37 3 місяці тому +1

    I want to ask, is it a good practise to think of tuples as a more default way of making iterables?
    tuples are more efficient, and i've heard the idea that "by default, things should be immutable, unless you know you will change the data" a few times.
    what I mean is: is it good to write tuples every time you need a tuple/list, and only use list if it makes more sense
    or am I overthinking it

    • @edgeman1135
      @edgeman1135 2 місяці тому

      Yeah for sure, tuples are pretty great! The changes for efficiency are quite minor when you compare it to switching data structures or straight up switching languages, but overall I'd say it's a good habit to pick up.

  • @egoragapov2033
    @egoragapov2033 3 місяці тому +2

    Thank you for the video! I believe we can use 'generators' too for memory efficient reasons?

  • @glorytoarstotzka330
    @glorytoarstotzka330 2 місяці тому

    I think when it comes to casting ranges/maps/filters to lists, it's important to note that it's still fine to do it for small scripts or low size things that you want to be able to print or have predictable behavior. sometimes you just wanna optimize for writing convenience and have no real consequences if it's something small scale

  • @jjggbbjunk
    @jjggbbjunk 3 місяці тому

    I barely know what I am doing, so I make all kinds of silly coding mistakes. Videos like these do help me, so thanks for this. Automating my powerflow studies has made me a much more efficient transmission engineer.

  • @oida10000
    @oida10000 3 місяці тому +3

    The problem with many iterables is that they are one times useables and not subscriptable, range is an exception.
    Try this:
    myr=range(10)
    for m in myr:
    print(m)
    print(myr[3])
    print(myr[6])
    Try the same with map or filter, after the loop they are empty.

    • @callbettersaul
      @callbettersaul 3 місяці тому +1

      Have you ever needed to iterate map or filter twice? Usually they are needed only once and it would be a waste of memory to not discard them. Like when you do map(filter(...)), it would be a waste to keep filter results in memory after being already used by map.

    • @oida10000
      @oida10000 3 місяці тому

      @@callbettersaul You would just need to keep the filter/map function in storage, plus a refrence to the **reusable** iterable - that is not that much.

    • @joshix833
      @joshix833 3 місяці тому

      Yes, most iterators are not re-usable, but iterables that are not iterators (like range, list, tuple) are re-usable

    • @atussentinel
      @atussentinel 3 місяці тому +1

      If you want to frequently subscribe an iterable which it does not support, you are probably using a wrong data structure.
      Occasional doing something a data structure is not optimized for is considered ok.

  • @krzysiekkrzysiek9059
    @krzysiekkrzysiek9059 2 місяці тому

    Perfect tips 👍

  • @bart5557
    @bart5557 2 місяці тому

    Great list! Curious about one thing tho. How did you add the "int()" around 1e6 so quickly? Done through a shortcut?

    • @TurkeyTray
      @TurkeyTray 28 днів тому +1

      highlighting text in PyCharm allows you to press an open parenthesis to enclose the entire thing in parenthesis. Then it's just as simple as pressing the left arrow twice and typing "int." As to how 1e6 was highlighted quickly, you can do ctrl + shift + arrow to highlight everything to the start/end of a word.

  • @ProfRoxas
    @ProfRoxas 3 місяці тому

    I like these examples, they can be quite common
    With the try-except blocks, i try to minimize the lines it has (bad habit from other languages, exceptions could use more resource than necessary) and be specific with the types, with some exception, but then I usually raise back the exception and only either print or log the exception to be verbose.
    Sometimes i even make custom exceptions to only catch what i really want to catch and let through what i didnt mean to catch like key or value errors
    The second one can be quite common, I take extra caution when i see them, because they can be simpler, but only work when the list is not modified, only checked through.
    One of my flying thought was to create a new variable and use the or operator to append to it (temp = targer or []), but then it would incorrectly append to the new object instead of target if target is an empty list
    The last example is especially useful on big data sets or even list comprehensions, because if i only need an iterable, then just by changing the [] to () makes it a memory efficient generator that won't create a temporary list (It's one of my must check thing at work, because it can be efficcient and very easy to change)

  • @TheJaguar1983
    @TheJaguar1983 3 місяці тому

    Funny thing about "range" is I used to use "xrange" in Python 2.7 for this exact reason.

  • @ProfMonkeys
    @ProfMonkeys 3 місяці тому +1

    I have taken to using a slightly different variant of your proposed replacement for mutable defaults. I prefer to use the 1 liner of:
    target = target or []
    It is certainly not perfect, but it ends up being so concise that new and old engineers alike can wrap their head around the idiom very easily. In the case where an empty list is explicitly passed in the list that gets appended to will not be the same instance as what was passed in, but if you are running into that little hole because you aren't capturing the output to a variable, then your code usually has bigger problems that should be addressed first.

    • @schwingedeshaehers
      @schwingedeshaehers 3 місяці тому

      the problem is, that there are situations, where you get an empty list, and it expects that these 2 are the same, in the function it will use the same, but another scope may not

    • @ProfMonkeys
      @ProfMonkeys 3 місяці тому

      @schwingedeshaehers that is absolutely another weakness of the model I tend to use. In nearly all of the cases I have found, however, that distinction has not mattered.
      In the few cases I have found where I explicitly need to disambiguate between using the default value and passing in an empty object, I tend to switch to using a sentinel obnect and being verbose to make it very clear that this is a place where that distinction matters.
      My preferred model is not perfect, but the expediency and ease of parsing the resulting code has been serving me very well so far.

    • @ProfMonkeys
      @ProfMonkeys 3 місяці тому +1

      @schwingedeshaehers a big part of why I feel this is unambiguous is the fact that such a method allows a default value for a parameter means that the function does not promise that the original object passed in will be modified in place. If I wanted to make a function that made such a promise, I would not allow a default value and would require it to be passed in explicitly.
      I also generally view modifying mutable arguments in place as a practice to be avoided in most situations because it can lead to other unexpected behaviors, unless that is explicitly designed in.
      Either the function would modify the list in place and return nothing, or it would create a copy of the list with the appended elements and return the copy but mixing the two behaviors together is something to be avoided.

    • @kaltaron1284
      @kaltaron1284 Місяць тому

      @@schwingedeshaehers You would also mask any error where your funtion recieves an unintended value that equates to false like 0.

  • @AmitabhGhuwalewala
    @AmitabhGhuwalewala Місяць тому

    In my experience, depending on the object being returned by the iterator/generator, it might be more computationally efficient to actually force the evaluation of the whole iterator, thereby sacrificing memory for time efficiency. It would depend on the scenario though - obviously not recommended as a rule of thumb. Be very careful about this and document why you think you need to do this when you do need it.

  • @little8138
    @little8138 3 місяці тому

    make a video for interview practice questions, It will help to so many

  • @6_nikki_9
    @6_nikki_9 2 місяці тому

    cool video 😎

  • @Zahlenteufel1
    @Zahlenteufel1 3 місяці тому

    Is there any reason why the second one exists? Is there any situation where we would want the function to remember in that way? Because it seems like a problem that should be removed from Python instead of forcing us to do the None check every time.

  • @DrDeuteron
    @DrDeuteron 2 місяці тому

    Catching bare exception is so bad. I worked a 7 figure NASA project that had it, and it went south on an unseen " " (space), that was caught and ignored, and the error it cause wasn't noticed for a month. They had java programmers in charge, so there there so many python violations...it was the only PJ I ever quit in disgust in 40 years. 5 years later they are following ALL my recommendations.

  • @rolandovillcaarias5112
    @rolandovillcaarias5112 3 місяці тому

    About bad habit #1, what is the difference using multiple except for multiple exceptions vs only one line for one except and multiple exceptions? Are both same? it is just code readability?

    • @callbettersaul
      @callbettersaul 3 місяці тому

      Not at all, multiple except/catch lines are preferred in the situations where you want to customise the behaviour upon each different exception. Like maybe for ValueError you want to print out "please enter a number", but for IndexError this wouldn't make sense so you print out "incorrect number instead". The customisation is limitless. If you just want to log the error, then there's no reason to use multiple except clauses.

  • @saitaro
    @saitaro 3 місяці тому +7

    Things like `my_list: range = range(10 ** 6)` is an overuse of typing which only clogs up the code. It doesn't provide any information, since it's clear what type the variable is.

    • @Indently
      @Indently  3 місяці тому +3

      Back then I would agree with you, but personally what is more important for me than a little bit of "clogging", is consistency. Typing 100% of my code is the approach I go for, I don't follow random rules or use special exceptions, I type everything.
      I constantly read in the comments that people all have their "special" typing rules, and that's great! But none of us will intuitively understand these "rules", so again, I type everything for consistency.
      You don't have to, but when you're teaching to millions of students, you can't always have the luxury of making up your own special case rules.

    • @saitaro
      @saitaro 3 місяці тому

      ​@@Indently I agree on consistency, though even Guido said that it is not necessary to type everything this way, nor it is theoretically possible for Python due to it's dynamic nature. The common rule is simple: type when it's not obvious right away (you suppose a list to be a list of strings) and when it will help an IDE to check and make suggestions (function signature as an example). `my_range: range = range(10)` looks redundant.

    • @Indently
      @Indently  3 місяці тому

      You're not going to like my objects then xD
      fruit: Fruit = Fruit()
      I know we're in Python, and I know I make it look like Java sometimes, but I think this consistent approach will lead to far less issues than letting people decided for themselves what's obvious and what isn't.
      This is only keeping into account that you plan to share your code with others. If you code for yourself, and don't plan to work with others or show your code to anyone else, obvious documentation and type annotations probably will not matter.

    • @thomaseb97
      @thomaseb97 3 місяці тому

      @@Indentlyyou can still be consistant while ignoring typing of certain things, i use typing alot as i feel dynamic typing was a mistake lmao, but for local variables i never use typing
      so i consistantly dont use typing on local variables, i always type my parameters and return, and always type my global variables/constants
      most modern languages also lean to this standard of typing, to not type local variables

    • @landsgevaer
      @landsgevaer 3 місяці тому +1

      The Zen of Python, L2:
      *Explicit is better than implicit*

  • @Hernell12
    @Hernell12 3 місяці тому +1

    For tip 2:
    target = target or [] is much cleaner than the if target is None: target = []

    • @swolekhine
      @swolekhine 3 місяці тому

      Not everyone knows about the or-shortcut you used there, so that might be a reason to prefer “if target is None”. But it is definitely a cool trick!

    • @antonk1620
      @antonk1620 3 місяці тому +2

      much cleaner will be if python allowed to safe init list and dicts in func params :)

    • @callbettersaul
      @callbettersaul 3 місяці тому +4

      As mentioned in another similar comment, if someone passes in an empty list, then your approach would replace that empty list even though None wasn't given as the argument. That can easily surprise anyone if they'd expect your function to modify their list in place.

  • @CarlesMateu
    @CarlesMateu 2 місяці тому

    Albeit, using range and similar objects is great for memory efficiency. Sometimes I feel most of us programmers, get scared by a list using 8 million bytes of memory... but that's *only* 8 Mbytes, out of the 16000 M bytes most of us have on our machines.
    Memory availability on modern machines has grown quite a lot, laptops with 16G are common, servers with 32, 64, and upwards are not rare things. So, sometimes, we spend too much time optimizing memory usage for things, that, in perspective, don't use so much of the available memory.
    That being said, in this case, the use of range vs a list is totally justified.

  • @rolandovillcaarias5112
    @rolandovillcaarias5112 3 місяці тому

    Hi, for bad habit number 2, is it better to validate: "if target is None" or "if not target"?

    • @dragweb7725
      @dragweb7725 3 місяці тому +2

      It depends if you want your function to accept other falsy values like {}, 0, (), False, "", or if you want it to type check whatever is given and raise an error or a warning when it is the wrong type. The thing is "if target is None" will only catch the None object, and "if not target" will catch any of the falsy values listed above

  • @barbarosteomankosoglu6602
    @barbarosteomankosoglu6602 3 місяці тому +1

    What app is this, looks really nice

    • @Indently
      @Indently  3 місяці тому

      We're in PyCharm, my friend :)

    • @barbarosteomankosoglu6602
      @barbarosteomankosoglu6602 2 місяці тому

      @@Indently Is mac and windows look different? Eventhough I have 24.1, it looks really older.

  • @nahidujjamanhridoy7129
    @nahidujjamanhridoy7129 2 місяці тому

    which ide are you using?

  • @auroragb
    @auroragb 2 місяці тому +1

    youtube bad habit: have chapter sections but no meaningful title.
    Clearly you weren't worried about spoiling the video as the thumbnail was a great summary. But with the chapter 1/2/3, it makes it hard for viewers interested in a particular item to jump to it

  • @andylem
    @andylem 3 місяці тому

    WHat editor is this?

  • @KeithKazamaFlick
    @KeithKazamaFlick 3 місяці тому

    yes sir!

  • @leokiller123able
    @leokiller123able 3 місяці тому

    This example for exception handling is not very good because in this case there is only one possible error case: ValueError, and I think in cases like this when there is only one possible exception case it is fine to use an empty except statement.

    • @Indently
      @Indently  3 місяці тому +3

      If there's only one possible error and you know it's a ValueError, why would you catch a bare Exception instead of a ValueError?
      Using a bare "except" just says that there's potentially something that will go wrong, and that you have no idea what it is.

    • @leokiller123able
      @leokiller123able 3 місяці тому

      @@Indently for less verbose code, and because I don't want to catch an object that I won't use, anyway people who will read my code will see what type of exception it is just by looking at the error message (in my print statement for example)

    • @callbettersaul
      @callbettersaul 3 місяці тому

      @@leokiller123able You're not forced to catch an object. If you don't plan on using the exception object, you just write "except ValueError" and omit the "as e". And making people look through your code to try to figure out the potential exceptions is not a good idea. And it gets worse as your project's size increases.

    • @schwingedeshaehers
      @schwingedeshaehers 3 місяці тому

      and there is at least one, probably at least 2 other errors possible

  • @rkdeshdeepak4131
    @rkdeshdeepak4131 3 місяці тому +5

    We can also use
    target = target or []

    • @emuccino
      @emuccino 3 місяці тому +8

      Note that there could be an unintended side affect when done this way. If an empty target list is passed as an argument, then this would replace it with a new empty list. While that probably is fine in most cases, there could be a scenario where a variable outside the scope of the function contains a reference to the original target list and will not be updated unless explicitly reassigned. Just something to keep in mind.

    • @maxmuster2016
      @maxmuster2016 3 місяці тому +2

      @@emuccino Thanks for pointing that out. A more safee one-liner would be target = [] if target is None else target. Why a one-liner? The excution is faster, because the processor can look ahead to predict the next lines of code.

    • @Lanxxe
      @Lanxxe 3 місяці тому

      ​​@@maxmuster2016it is also kinda confusing so I would avoid that and just go for the traditional way. Furthermore, you would need to pass in None every time right

    • @kaltaron1284
      @kaltaron1284 Місяць тому

      @@Lanxxe The ternary one-liner version of if takes a bit getting used to but IMHO is just as readable as a the normal version as long as all parts are short like in this case. If you can't get it on one line it's probably not a good idea but the same is true for if-statements.

  • @-wx-78-
    @-wx-78- 2 місяці тому

    Reminds me of Unix ed, which respond "huh?" to any error (without "huh" part, you know ;-).

  • @_dzudzu_
    @_dzudzu_ 3 місяці тому

    1:28 I have to correct you! I was paid zero dollars actually. It was made for homework

  • @hikaritsumi2123
    @hikaritsumi2123 23 дні тому

    Haha I wish I could correctly handle the error from 3rd party service with no documentation
    As web dev it really get on my nerve when the team decide to return 400 to Frontend because the code CAN explode for basically any reason
    try:
    ...(everything)
    except Exception as e:
    return
    At least I return 500 to indicate that it is ME who need to correct something, and in an ideal scenario it shouldn't happen because I handle every case it could conceivebly happen in a more logical way.
    ..am I becoming Bob?

  • @timschulz9563
    @timschulz9563 2 місяці тому

    6:59 But isn't the type hint wrong then? Shouldn't it be Optional[list[T]]?

    • @Indently
      @Indently  2 місяці тому

      Yes it's wrong, and it's my fault for not running mypy before sharing the code with you guys.

  • @rezarg
    @rezarg Місяць тому

    I'm not sure if this is as bad as I think it is, but I once saw my friend coding in Python and they had "import os" in almost every function instead of just having it once at the top of the file.

    • @Indently
      @Indently  Місяць тому

      Now that's overkill xD

  • @user-uc6wo1lc7t
    @user-uc6wo1lc7t 2 місяці тому

    target: list[T] = None... Meh...
    Maybe Optional[list[T]] would be better? I don't know why your type checker doesn't complain about your code example, but complains about mutable default in function signature...

  • @popel_
    @popel_ 3 місяці тому

    In my own project with 3k lines of code the biggest problem in syntax is 'except Exception' 😂
    But I think it doesn’t matter there because I catching errors from database

    • @Indently
      @Indently  3 місяці тому +1

      Fast to write, but huge pain later ahah

    • @user-vt9bp2ei1w
      @user-vt9bp2ei1w 3 місяці тому +1

      The main problem with 'except Exception' is that Exception subclasses include SyntaxError, NameError, IndentationError and TabError.
      These are exceptions that may be thrown by any line and should not be caught.

    • @callbettersaul
      @callbettersaul 3 місяці тому +1

      @@user-vt9bp2ei1w I tried to catch the errors you mentioned and I only managed to catch NameError. All other errors were still thrown despite the 'except Exception'.

    • @callbettersaul
      @callbettersaul 3 місяці тому +1

      I would assume there would be a general superclass for all those database exceptions. I would suggest catching that instead. Sweeping a critical "random" exception under the rug can be fatal in some circumstances.

    • @joshix833
      @joshix833 3 місяці тому

      ​@@squishy-tomatono bare except is like except BaseException

  • @AntonFrolov1
    @AntonFrolov1 3 місяці тому +1

    6:34
    target = target or []
    is not as good as
    target = [] if target is None else target
    see the comments below

  • @bhai431
    @bhai431 2 місяці тому +1

    *Please Make New Video On Making Telegram Bot wich work 24×7 and please must share the Script/Codes otherwise its very very difficult for us*

    • @bhai431
      @bhai431 2 місяці тому +1

      I have need seeing your old video in this topic but unable to make from 10 days! Even the codes are not available there so I need to type all codes from your videos 😨🥲🥲🥲

  • @aspizuwastaken
    @aspizuwastaken 3 місяці тому +2

    i know your watching this mcoding

    • @Indently
      @Indently  3 місяці тому +1

      I'm a huge fan of mCoding (if you're reading this mCoding) ;)

  • @user-co9rc1kp7p
    @user-co9rc1kp7p 3 місяці тому +3

    I often see people using Ellipsis to define abstract method body instead of pass or NotImplemented. I guess this is weird, so use it either to show you need to code there something later or for "there could be anything" purpose. At the same time Ellipsis is ok for using inside the Protocol methods, because you're allowed to call these methods. Sry 4my Eng

  • @rondamon4408
    @rondamon4408 3 місяці тому +2

    When you said about bad habits with python I thought that you were going to show visual studio code

  • @Nape420
    @Nape420 3 місяці тому +6

    Few suggestions:
    1. Use the `typing.List` type annotation instead of python's `list`. It's much more flexible and linter friendly
    2. If a parameter is optional (i.e. its None by default) annotate it as such with the `typing.Optional` or use the (>= 3.10) union syntax `|` (e.g. int | None )

    • @__mrmino__
      @__mrmino__ 3 місяці тому +4

      typing.List is deprecated

    • @Indently
      @Indently  3 місяці тому +1

      I don't understand the first suggestion, in what way is it more flexible?
      For the second one I messed up, and made the video without running mypy so I accept that I will get roasted for that xD

    • @coladock
      @coladock 3 місяці тому

      Maybe he wants to express that sometimes List can be upcast to Sequence.
      My work force us pass linting and mypy. Optional is a good habits but some times return Optional may cause mypy warning make it more difficult to fix😅.

    • @callbettersaul
      @callbettersaul 3 місяці тому +3

      1. Built-in type hints were added in 3.9 and that's the exact reason they deprecated typing.List and others. So no, you should not use it.
      2. Optional is not meant to be used with default arguments, as the value None is not actually permitted there, it's merely a placeholder value. Optional is meant to be used when the explicit value of None is allowed. It even says that in the python documentation.

    • @user-co9rc1kp7p
      @user-co9rc1kp7p 3 місяці тому

      Actually, python core devs improved list to be a type annotation as well despite the fact that typing.List has already existed. So later, they did such thing with tuple. I guess there should be a good reason (imho remove useless import, i dont know). What did you mean about flexible? Sry for my Eng :)

  • @nickeldan
    @nickeldan 3 місяці тому

    if x == True:
    This one makes me want to die.

  • @chestnutmongrel
    @chestnutmongrel 3 місяці тому

    A really bad habit to avoid is create a video with that generic naming - zero new information in five minutes, thankyouverymuch...

    • @Indently
      @Indently  3 місяці тому +6

      You might not have noticed, but the thumbnail gives you a little *hint* about what will be in the video ;)
      Thank you for your constructive comment nonetheless! Have a great week :)

    • @marcellfarkas5889
      @marcellfarkas5889 3 місяці тому

      This naming convention is very common unfortunately. By the way this video was useful for me.

    • @callbettersaul
      @callbettersaul 3 місяці тому +2

      @@Indently Probably difficult to find it in a year tho ("I think I remember Indently making an awesome video about x, let me try finding it").

    • @Indently
      @Indently  3 місяці тому +2

      It's time to create an add-on that allows you to save videos to your own playlist with your own names xD