It actually is Tuesday, the 13th for us in Spain (idk why)
@mCoding4 ай бұрын
I never paid attention to the print flush behavior before, it makes sense now that I think about it. Thanks for pointing that out!
@jeffbeasley82354 ай бұрын
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.
@Allenrythe4 ай бұрын
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.
@alberthalbert11534 ай бұрын
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.
@michaelthomson814 ай бұрын
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
@miquelvazquez45444 ай бұрын
wow didn't know that was possible! thxx
@PanduPoluan4 ай бұрын
Not just for that example. But for every single run-on print()s
@user_Esq4 ай бұрын
Beginners may not know the f-magic
@marcotroster82474 ай бұрын
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.
@jurgenrusch40414 ай бұрын
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.
@Oddys19834 ай бұрын
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
@marckiezeender4 ай бұрын
8:47 data[0] = data[0] + [3] does NOT give the same result as data[0] += [3]
@hansdietrich14964 ай бұрын
Yeah, which makes this case even weirder.
@jamesarthurkimbell4 ай бұрын
He was trying to say that, by contrasting "in-place addition" with "assignment." But yeah, it would have been better to demonstrate.
@kevinryan29924 ай бұрын
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
@saitaro4 ай бұрын
It's used in the stdlib, too. A function cached with a functools caching decorator get the .cache_clear() method.
@ArpadHorvathSzfvar4 ай бұрын
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.
@diegomerino99394 ай бұрын
Many thanks for your very instructive videos. Wanted to ask you what font you are using in the video.
@thisoldproperty4 ай бұрын
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
@ayehavgunne4 ай бұрын
I like 'for, else'. i just always comment the 'else' with # nobreak
@aghnos94 ай бұрын
Have you considered using the multi cursor to avoid wasting video time just changing repetitive things line by line Love your videos!
@gavin.burnell4 ай бұрын
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!
@stokhosursus4 ай бұрын
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
@macong12173 ай бұрын
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.
@CalvinJKu4 ай бұрын
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….😅
@Efecretion18 күн бұрын
You should demonstrate hoisting -- it can be very confusing!
@midinerd4 ай бұрын
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]"
@west221bАй бұрын
I wonder if the `for` loop variable's scope has anything to do with `for` having an `else` clause.
@Impatient_Ape4 ай бұрын
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.
@ArjanCodes4 ай бұрын
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.
@rivendrive4 ай бұрын
3.12 shows up in the outputs in some of the examples
@CalvinJKu4 ай бұрын
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….
@AloisMahdal4 ай бұрын
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).
@DrDeuteron4 ай бұрын
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.
@orgadish4 ай бұрын
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.
@TheEvertw4 ай бұрын
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.
@MariuszWoloszyn4 ай бұрын
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.
@edgeeffect4 ай бұрын
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. ;)
@kellymoses85664 ай бұрын
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.
@lucasmultigaming42434 ай бұрын
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,)'.
@user_Esq4 ай бұрын
Are the intended advantages of integer caching measurable?
@nigh_anxiety4 ай бұрын
It prevents new int objects from being created and destroyed for most for loops over a typical value ranges.
@tomaszolszewski97844 ай бұрын
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"
@drorata4 ай бұрын
The one with immutable default values of functions once cost me a few good hours to figure out.
@DrDeuteron4 ай бұрын
wait, isn't the >>>a.some_attr is X.some_attr rendered pointless by the weirdness No 1: integer caching?
@ramimashalfontenla13124 ай бұрын
Love this kind of videos
@ArjanCodes4 ай бұрын
Glad you like them!
@roccococolombo20444 ай бұрын
Switching windows is confusing. Why not use side-by-side windows ?
@nigh_anxiety4 ай бұрын
Probably for viewers on mobile. Using a single window allows him to keep more content on screen with a larger font size.
@peterweston65884 ай бұрын
I remember using a function attribute as a kind of static variable, but I cant' remember the context.
@sinasalahshour4 ай бұрын
8:46 adding two lists with + sign doesn't mutate the original lists. are you sure the syntactic sugar expands to that syntax?
@sinasalahshour4 ай бұрын
>>> a1 += [3] # Uses __iadd__, modifies a1 in-place >>> b1 = b1 + [3] # Uses __add__, creates new list, assigns it to b1
@user-fn5ji6pk8r2 ай бұрын
As as been mentionned already at least once in the comments, the statement "if n: print("n is True")" would print for any number n that is non-zero
@marksegall97664 ай бұрын
have you ever imported 'this'?
@brianb.63564 ай бұрын
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.
@marckiezeender4 ай бұрын
Even with strings, the compiler will optimize them to be the same object. You'd have to use something else
@ArjanCodes4 ай бұрын
You’re right, thanks for pointing that out! There’s still the confusing mix-up between class vs instance variables though.
@danilshein46124 ай бұрын
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.
@XRay7774 ай бұрын
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
@__wouks__4 ай бұрын
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.
4 ай бұрын
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
@stokhosursus4 ай бұрын
I have a good example to explain data classes, but my comments keep getting removed. How is it best to share this?
@daniel-jerrehian4 ай бұрын
The second one has killed me before. I really wish it provided a new list in that scenario
@asagiai49653 ай бұрын
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.
@aim29864 ай бұрын
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?
@mmilerngruppe4 ай бұрын
my last weird finding is the round(). that function do rounding, but in some surprising way.
@lucasmultigaming42434 ай бұрын
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.
@mmilerngruppe4 ай бұрын
@@lucasmultigaming4243 huh, I didn't realize the IEEE745 is about rounding too. thank you to pointing that out.
@xiggywiggs4 ай бұрын
True + True = 2 is some Dr Seuss stuff and now I want a Dr Seuss style silly rhyming book about coding
@amitshogun4 ай бұрын
Scope issue when initializing new variable in try except clause.
@rafiullah-zz1lf4 ай бұрын
The most frustating thing i found were the errors
@therealdebater4 ай бұрын
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.)
@chrisw14623 ай бұрын
Integer Caching: I don't think you can call it 'caching' when it's simply pointing both variables to the same object.
@sinancetinkaya4 ай бұрын
Nice to learn For-Else 👍
@vladimirtchuiev22184 ай бұрын
Why in 8 you would ever use the "else:"? If you remove it you would get exactly the same functionality, no?
@lucasmultigaming42434 ай бұрын
It would not because the `print("Does not exist")` statement would be called even if an element was found.
@sebastianrossetti61674 ай бұрын
Loved the BOUNS
@shivanshusharma-y8f4 ай бұрын
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()
@TankaNafaka4 ай бұрын
Just watch any of James Powell talks on YT and than you know python its weird. 😂 BR from 🇩🇰
@timedebtor4 ай бұрын
6 - (True).denominator
@alexivanov41574 ай бұрын
Is Not Second
@hoseynamiri4 ай бұрын
dark magic
@user_563pol09dfg4 ай бұрын
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
@AlexV64 ай бұрын
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...
@dapodix4 ай бұрын
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.
@cezartorescu4 ай бұрын
None of them are weird if you understand and accept working with Python as it is....
@ayehavgunne4 ай бұрын
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.
@scootergirl36623 ай бұрын
You could say that about any language. Weird is subjective. Like he says, it’s weird to a newbie maybe.