13 Python Quirks That Will Surprise You

แชร์
ฝัง
  • เผยแพร่เมื่อ 23 พ.ย. 2024

ความคิดเห็น • 90

  • @ArjanCodes
    @ArjanCodes  2 หลายเดือนก่อน +17

    I hope you guys are not superstitious 😁.

    • @alvaroe2704
      @alvaroe2704 2 หลายเดือนก่อน +1

      It actually is Tuesday, the 13th for us in Spain (idk why)

  • @jeffbeasley8235
    @jeffbeasley8235 2 หลายเดือนก่อน +35

    That last section was very hard to follow with the switching between windows and the high number of things being printed. Comments next to the lines with the results would have helped a lot, or maybe using a jupyter notebook could have worked as well.

    • @Allenrythe
      @Allenrythe 2 หลายเดือนก่อน +1

      It could have been better shown if he showed that dataclass objects don't have class attributes. It's definitely confusing when you don't have the attributes defined on different scope/indentation levels.

  • @mCoding
    @mCoding 2 หลายเดือนก่อน +10

    I never paid attention to the print flush behavior before, it makes sense now that I think about it. Thanks for pointing that out!

  • @michaelthomson81
    @michaelthomson81 2 หลายเดือนก่อน +23

    Why not use f-strings to show the evaluated expression as well as the result to save flipping between screens?
    E.g.
    >>> print(f"{(1 == True) = }")
    (1 == True) = True

    • @miquelvazquez4544
      @miquelvazquez4544 2 หลายเดือนก่อน +1

      wow didn't know that was possible! thxx

    • @PanduPoluan
      @PanduPoluan 2 หลายเดือนก่อน +1

      Not just for that example. But for every single run-on print()s

    • @user_Esq
      @user_Esq 2 หลายเดือนก่อน

      Beginners may not know the f-magic

  • @marcotroster8247
    @marcotroster8247 2 หลายเดือนก่อน +6

    In C, false is zero and everything else is true. And that's exactly the way while loop conditions work in Python as well. You can put a number and when it's not 0, it's true and the loop continues.

  • @alberthalbert1153
    @alberthalbert1153 2 หลายเดือนก่อน +3

    My other favorite easter egg in Python - in any REPL, type "from this import that" - it prints the zen of Python poem. But if you go look in the module, the string is encrypted with a substitution cipher!
    Side note, if you use ctrl+alt+up/down, you can do multiline cursors in VS Code (similar to ctrl + click). So if you have a bunch of statements that line up in a columnar way you can edit them all at the same time. PyCharm has similar functionality but you have to press ctrl 2x in quick succession and hold it down on the second press, then use the arrow keys, which I like a lot less.

  • @diegomerino9939
    @diegomerino9939 2 หลายเดือนก่อน

    Many thanks for your very instructive videos.
    Wanted to ask you what font you are using in the video.

  • @marckiezeender
    @marckiezeender 2 หลายเดือนก่อน +11

    8:47 data[0] = data[0] + [3] does NOT give the same result as data[0] += [3]

    • @hansdietrich1496
      @hansdietrich1496 2 หลายเดือนก่อน

      Yeah, which makes this case even weirder.

    • @jamesarthurkimbell
      @jamesarthurkimbell 2 หลายเดือนก่อน

      He was trying to say that, by contrasting "in-place addition" with "assignment." But yeah, it would have been better to demonstrate.

  • @jurgenrusch4041
    @jurgenrusch4041 2 หลายเดือนก่อน

    Hi Arjan, again a very nice video, so thanks for that!
    With respect to the function attributes: yes at first it may seem strange that such an attribute definition on a function is possible. On the other hand, if you look at the output of dir(functionName) you can see automatically defined attributes, all of them being dunder-attributes (starting and ending with double underscores).
    Example is that a function documented with a docstring has that documentation stored in the attribute __doc__.
    Knowing that dunder-attributes are usually defined by Python itself, it makes sense that non-dunder attributes are available to the programmer. I agree with you that it is not common use to do.
    As mentioned by another reader, using decorators on functions is a more widely used practice to obtain functionality that could otherwise be reached using function attributes.

  • @midinerd
    @midinerd 2 หลายเดือนก่อน +1

    What version of python do I need to use, or what should I import, for your function signature in Ex#2 to work?
    def append_to_list[T]... 3.11.4 doesn't like the "[T]"

  • @AloisMahdal
    @AloisMahdal 2 หลายเดือนก่อน +1

    9 has nothing to do with Python, it's just how OS works. The output is line-buffered by default, so OS won't pass it on to the terminal before it contains
    (which you purposefully suppressed) or the program exits.
    OS provides a way to force buffer flush (which is what `flush=True` does) or to switch to other buffer strategy (eg. by buffer size).

  • @aghnos9
    @aghnos9 2 หลายเดือนก่อน

    Have you considered using the multi cursor to avoid wasting video time just changing repetitive things line by line
    Love your videos!

  • @macong1217
    @macong1217 หลายเดือนก่อน

    Function name starts with double underscore inside a class can cause big trouble for child class. It kind of makes it an exclusive method for the super class.

  • @Oddys1983
    @Oddys1983 2 หลายเดือนก่อน

    Great stuff! I did not hear about NotImpemented (and, obviously, antigravity 😂) before this video. I only think that while most of the other features are caused by the peculiarities of the language implementation, item 6 is not truly weird, as it is what anyone might expect from string immutability and variable reassignment

  • @XRay777
    @XRay777 2 หลายเดือนก่อน +3

    Not sure if this classifies as weirdness, if anything it is perhaps rather unexpected but in a good way: In python almost anything is fair game. Asigning attributes that were not defined on the class? Sure! Swap out methods using moneky-patching!? Go ahead! Hooking into the import system to allow loading modules directly from pip? Why not. But if you try to return a negative number from `__len__` the interpreter will scream at you =D

  • @MariuszWoloszyn
    @MariuszWoloszyn 2 หลายเดือนก่อน

    It would be beneficial if you used the Jupyter notebook for this video.
    Rather than switching between outputs you could show them in line between code.

  • @orgadish
    @orgadish 2 หลายเดือนก่อน +1

    Since `some_attribute` is an integer, doing `a.some_attribute is b.some_attribute` will always return True if the values are the same, even if they're not references to each other.

  • @thisoldproperty
    @thisoldproperty 2 หลายเดือนก่อน

    At 15:00 the for/else loop is discussed. Raymond Hettinger gave a talk "Transforming Code into Beautiful, Idiomatic Python" at 18:00 he suggested that the 'else' should have been called 'nobreak'. He also mentioned that Python has an inbuild capability to find (so long as it's an interable). Something like:
    item = next((x for x in iterable if condition(x)), None)
    if item:
    # Found the item, do something

    • @ayehavgunne
      @ayehavgunne 2 หลายเดือนก่อน

      I like 'for, else'. i just always comment the 'else' with # nobreak

  • @danilshein4612
    @danilshein4612 2 หลายเดือนก่อน +5

    About "weirdness" of class and instance variable: it's confusing only when you don't know the Python language. It's called MRO and well described in the official documentation.

  • @kevinryan2992
    @kevinryan2992 2 หลายเดือนก่อน +2

    Function attributes are cursed but can also be pretty awesome. Being able to count invocations, automatically log calls, etc. You can also usually accomplish the same with decorators though

    • @saitaro
      @saitaro 2 หลายเดือนก่อน

      It's used in the stdlib, too. A function cached with a functools caching decorator get the .cache_clear() method.

    • @ArpadHorvathSzfvar
      @ArpadHorvathSzfvar 2 หลายเดือนก่อน

      I agree. I think there was the possibility to implement memoization (caching) maybe before any decorator (like lru_cache) existed in the std library for it. And you can't find any better place the cache dictionary than into the function itself as an attribute.

  • @tomaszolszewski9784
    @tomaszolszewski9784 2 หลายเดือนก่อน

    I would also add those:
    1) type(type) is type
    2) issubclass(type, object) and isinstance(object, type)
    3) "a"[0][0][0][0][0] == "a"

  • @stokhosursus
    @stokhosursus 2 หลายเดือนก่อน

    Essentially, data classes use class-level descriptor to store default values for instance attributes, class attributes are only defined by leaving variable untyped, and this can be seen with a simple example I’m happy to share if comments would allow. 25:30

  • @CalvinJKu
    @CalvinJKu 2 หลายเดือนก่อน

    And to add to this discussion, two things I found really weird about Python. 1. Circular imports are not allowed but can be bypassed by importing only the modules. 2. Also about imports. Python makes it really hard when you have a file in a folder in which you’d like import another file from another folder which is of the same level in your repo tree structure. Usually it’s no big deal but when you wanna put all your tests in a folder and import functions and classes from other folders it’s a nightmare. To be honest I’m still quite confused what’s the best practice for this. For the moment I’m using pip install -e . And add a setup file. But I’m not sure this is the best way….

  • @gavin.burnell
    @gavin.burnell 2 หลายเดือนก่อน

    I find passing mutable parameters into a function and then modifying them inside the function and having that change appear outside the function to be something that trips me up occasionally.
    On the otherhand else clauses on for loops and while loops make total sense!

  • @Impatient_Ape
    @Impatient_Ape 2 หลายเดือนก่อน +2

    Arjan, do you think you could tell viewers at the beginning of a video which version of Python you were using? It's frustrating to type in your examples only to have them crash because of version issues.

    • @ArjanCodes
      @ArjanCodes  2 หลายเดือนก่อน +2

      I will normally use the latest version of Python in my videos. I do put the Python version in the pyproject file for each example in the Git repository (see link in the description). So if you work from that, you shouldn’t have that problem anymore.

    • @rivendrive
      @rivendrive 2 หลายเดือนก่อน

      3.12 shows up in the outputs in some of the examples

  • @TheEvertw
    @TheEvertw 2 หลายเดือนก่อน

    The delayed print is not Python-specific. That buffering behaviour is standard for all programming languages I know of. Because for most situations, the overhead of printing is huge, and the program only wants to incur this overhead when it is useful to the user. I.e. when a sentence is completed.

  • @DrDeuteron
    @DrDeuteron 2 หลายเดือนก่อน

    The class attribute behavior is great. An instance look up starts at "self", and then checks type(self). It makes class attributes the place to set instance defaults. When I see:
    self.foo = foo and "foo" is NOT a dunder init argument, I lose it.
    Example: a car class:
    class Car:
    crashes = 0
    def crash(self):
    self.crashes += 1
    then:
    >>>car = Car()
    >>>car.crashes
    0
    is the class variable. But after:
    >>>car.crash()
    >>>car.crashes
    1
    is the instance attribute.
    Python is a language where, as with timer.counter, and the main() at 21:40 , you should never modify instance attributes outside of instance methods, Major code smell.

  • @kellymoses8566
    @kellymoses8566 2 หลายเดือนก่อน

    I recently discovered behavior that surprised me. If you create a nested Tuple like ('a', ('b')) Python strips the single element tuple which leaves ('a', 'b') which broke my iteration code so I had to replace it with a list, which is NOT removed.

    • @lucasmultigaming4243
      @lucasmultigaming4243 2 หลายเดือนก่อน +2

      A tuple is not defined by parentheses in Python, it's just defined by commas, so `a = (1, 2)` is the same as `a = 1, 2`. To get a tuple with just one element, you have to write `a = 1,` or `a = (1,)'.

  • @CalvinJKu
    @CalvinJKu 2 หลายเดือนก่อน +1

    Before I followed this channel I never actually used dataclasses so it wasn’t such a big deal to me. And to make sure I don’t get confused I always use all caps to define class attributes. But then I found this channel and I soon realized how convenient data classes. Now I’m starting to get confused….😅

  • @Lolwutdesu9000
    @Lolwutdesu9000 2 หลายเดือนก่อน

    Any idea why we can't mess around with Python built-in function attributes like in point number 12?

  • @drorata
    @drorata 2 หลายเดือนก่อน

    The one with immutable default values of functions once cost me a few good hours to figure out.

  • @brianb.6356
    @brianb.6356 2 หลายเดือนก่อน +1

    I have an objection to part 13!
    While everything you said was true, there's a bug in your demonstration for why it's true that goes back to an earlier part. Since small integers are always cached, `a.some_attribute is b.some_attribute` only checks their value (as long as they're both small integers). Should've assigned a string to demonstrate they're exactly the same object.

    • @marckiezeender
      @marckiezeender 2 หลายเดือนก่อน

      Even with strings, the compiler will optimize them to be the same object. You'd have to use something else

    • @ArjanCodes
      @ArjanCodes  2 หลายเดือนก่อน +2

      You’re right, thanks for pointing that out! There’s still the confusing mix-up between class vs instance variables though.

  • @edgeeffect
    @edgeeffect 2 หลายเดือนก่อน

    This is nice, speaking as someone who does far more JavaScript than Python, it's nice to see Python taking some of the abuse that's normally thrown at JavaScript. ;)

  • @stokhosursus
    @stokhosursus 2 หลายเดือนก่อน

    I have a good example to explain data classes, but my comments keep getting removed. How is it best to share this?

  • @__wouks__
    @__wouks__ 2 หลายเดือนก่อน

    With that for-else (or even while-else) part with break I normally just put a comment with the else like this: "else: # no break". I believe it was also mentioned at one of the PyCon videos by someone that it would have been better if the called the else there nobreak. Adding this comment normally makes it much clearer what is happening.
    I also think of this as an actual if-else statement. So if you get to the if {condition} part and the condition is False you go to else otherwise you go inside the if block. Now let's say inside the if block you return / break your else part would never run. With the for-else statement you can think of the "for item in items" part as the if condition, but the condition is checked with each iteration. If it is false here (like the iterable/iterator is empty or the loop is done) it goes to else instead, because that condition suddenly turned into a false statement.

  • @roccococolombo2044
    @roccococolombo2044 2 หลายเดือนก่อน +2

    Switching windows is confusing. Why not use side-by-side windows ?

    • @nigh_anxiety
      @nigh_anxiety 2 หลายเดือนก่อน

      Probably for viewers on mobile. Using a single window allows him to keep more content on screen with a larger font size.

  • @peterweston6588
    @peterweston6588 2 หลายเดือนก่อน

    I remember using a function attribute as a kind of static variable, but I cant' remember the context.

  • @DrDeuteron
    @DrDeuteron 2 หลายเดือนก่อน

    wait, isn't the
    >>>a.some_attr is X.some_attr
    rendered pointless by the weirdness No 1: integer caching?

  • @ramimashalfontenla1312
    @ramimashalfontenla1312 2 หลายเดือนก่อน +1

    Love this kind of videos

    • @ArjanCodes
      @ArjanCodes  2 หลายเดือนก่อน +1

      Glad you like them!

  • @user_Esq
    @user_Esq 2 หลายเดือนก่อน

    Are the intended advantages of integer caching measurable?

    • @nigh_anxiety
      @nigh_anxiety 2 หลายเดือนก่อน

      It prevents new int objects from being created and destroyed for most for loops over a typical value ranges.

  • @xiggywiggs
    @xiggywiggs 2 หลายเดือนก่อน

    True + True = 2 is some Dr Seuss stuff and now I want a Dr Seuss style silly rhyming book about coding

  • @asagiai4965
    @asagiai4965 25 วันที่ผ่านมา

    I wonder if these are quirks or just built-in in Python.
    It will be weird if functions in Python are reference type.
    I think C# or Java also have NotImplementedError equivalent.
    Actually, in most languages, true and false are integer or 1 and 0 they are not subclasses.
    Python putting "else" everywhere is probably a meme.
    What's next comprehension with else ?
    For the last one I think functions having attributes explains this quirks.

  • @marksegall9766
    @marksegall9766 2 หลายเดือนก่อน +1

    have you ever imported 'this'?

  • @daniel-jerrehian
    @daniel-jerrehian 2 หลายเดือนก่อน

    The second one has killed me before. I really wish it provided a new list in that scenario

  • @chrisw1462
    @chrisw1462 หลายเดือนก่อน

    Integer Caching: I don't think you can call it 'caching' when it's simply pointing both variables to the same object.

  • @aim2986
    @aim2986 2 หลายเดือนก่อน

    The fact that ___iadd___ method of lists just extend the list instead of creating a new list is a very weird design choice imo. Like why would u do that?

  • @rafiullah-zz1lf
    @rafiullah-zz1lf 2 หลายเดือนก่อน +1

    The most frustating thing i found were the errors

  • @mmilerngruppe
    @mmilerngruppe 2 หลายเดือนก่อน

    my last weird finding is the round(). that function do rounding, but in some surprising way.

    • @lucasmultigaming4243
      @lucasmultigaming4243 2 หลายเดือนก่อน

      Check IEEE-754 rounding rules, it's not specific to Python. It's the same reason why 0.1 + 0.2 = 0.30000000000000004 in Python like in any other programming language that follows IEEE-754.

    • @mmilerngruppe
      @mmilerngruppe 2 หลายเดือนก่อน

      @@lucasmultigaming4243 huh, I didn't realize the IEEE745 is about rounding too. thank you to pointing that out.

  • @sinancetinkaya
    @sinancetinkaya 2 หลายเดือนก่อน

    Nice to learn For-Else 👍

  • @therealdebater
    @therealdebater 2 หลายเดือนก่อน

    So ... sometimes Python can bite you in the asp? 🤣
    (Very good video, by the way, and be assured, people, that all programming languages have quirks.)

  • @sebastianrossetti6167
    @sebastianrossetti6167 2 หลายเดือนก่อน

    Loved the BOUNS

  •  2 หลายเดือนก่อน

    Examples with instance/class attributes using integer and is operator is not verify compelling imo the fact that a.some_attribute is X.some_attribute return True does not prove your point as 2 might be store in instance __dict__ and in class __dict__ but as integers are cached it will be True anyway

  • @vladimirtchuiev2218
    @vladimirtchuiev2218 2 หลายเดือนก่อน

    Why in 8 you would ever use the "else:"? If you remove it you would get exactly the same functionality, no?

    • @lucasmultigaming4243
      @lucasmultigaming4243 2 หลายเดือนก่อน

      It would not because the `print("Does not exist")` statement would be called even if an element was found.

  • @amitshogun
    @amitshogun 2 หลายเดือนก่อน

    Scope issue when initializing new variable in try except clause.

  • @shivanshusharma-y8f
    @shivanshusharma-y8f 2 หลายเดือนก่อน

    Recently on medium i found this, which I couldn't even think of.
    from somewhere import get_dog
    from elsewhere import create_default_dog
    dog = get_dog() # 5% chance of returning None instead of a Dog object
    (dog or create_default_dog()).bark()

  • @TankaNafaka
    @TankaNafaka 2 หลายเดือนก่อน

    Just watch any of James Powell talks on YT and than you know python its weird. 😂 BR from 🇩🇰

  • @timedebtor
    @timedebtor 2 หลายเดือนก่อน

    6 - (True).denominator

  • @alexivanov4157
    @alexivanov4157 2 หลายเดือนก่อน +1

    Is Not Second

  • @hoseynamiri
    @hoseynamiri 2 หลายเดือนก่อน

    dark magic

  • @user_563pol09dfg
    @user_563pol09dfg 2 หลายเดือนก่อน

    for me the following python behavior is strange (however i realize the reason);
    x = 1
    y = 2
    def one_plus_two():
    return x + y
    print(one_plus_two()) # output is 3

  • @AlexV6
    @AlexV6 2 หลายเดือนก่อน

    If I were you, I would learn and use Jupiter notebooks for my videos or found a clever way to video edit the console output in the IDE window. Right now, your presentation skill is below average...

    • @dapodix
      @dapodix 2 หลายเดือนก่อน

      Are you trying to manipulate him into using your favourite tool?😅 It definitely comes across that way.
      I don't even use vscode and I don't have trouble following along when he switches screens.

  • @sinasalahshour
    @sinasalahshour 2 หลายเดือนก่อน

    8:46
    adding two lists with + sign doesn't mutate the original lists. are you sure the syntactic sugar expands to that syntax?

    • @sinasalahshour
      @sinasalahshour 2 หลายเดือนก่อน

      >>> a1 += [3] # Uses __iadd__, modifies a1 in-place
      >>> b1 = b1 + [3] # Uses __add__, creates new list, assigns it to b1

  • @cezartorescu
    @cezartorescu 2 หลายเดือนก่อน +12

    None of them are weird if you understand and accept working with Python as it is....

    • @ayehavgunne
      @ayehavgunne 2 หลายเดือนก่อน +1

      These actually make sense when you know why it is the way it is. And Python has good reasons for pretty much all of these 'quirks'.
      But if you look at Javascript then there are TONNS of quirks that are not justified.

    • @scootergirl3662
      @scootergirl3662 หลายเดือนก่อน +1

      You could say that about any language. Weird is subjective. Like he says, it’s weird to a newbie maybe.