Python's most DISLIKED __dunder__ (and what to use instead)

Поделиться
HTML-код
  • Опубликовано: 31 май 2024
  • What is your least favorite?
    What is the most universally despised _dunder_ method in Python? It's __del__! From it's non-obvious relationship with del, to it's exception-ignoring behavior, to the uncertainty of whether the interpreter will call it 0 or multiple times, it's a real mess!
    ― mCoding with James Murphy (mcoding.io)
    Source code: github.com/mCodingLLC/VideosS...
    with statement docs: docs.python.org/3/reference/c...
    dunder del docs: docs.python.org/3/reference/d...
    weakref docs: docs.python.org/3/library/wea...
    Plus equals video: • Python's sharpest corn...
    Dunder new video: • __new__ vs __init__ in...
    Metaclasses video: • Metaclasses in Python
    SUPPORT ME ⭐
    ---------------------------------------------------
    Patreon: / mcoding
    Paypal: www.paypal.com/donate/?hosted...
    Other donations: mcoding.io/donate
    Top patrons and donors: Jameson, Laura M, Vahnekie, Dragos C, Matt R, Casey G, Johan A, John Martin, Jason F, Mutual Information, Neel R
    BE ACTIVE IN MY COMMUNITY 😄
    ---------------------------------------------------
    Discord: / discord
    Github: github.com/mCodingLLC/
    Reddit: / mcoding
    Facebook: / james.mcoding
  • НаукаНаука

Комментарии • 194

  • @hemerythrin
    @hemerythrin 2 года назад +244

    I would love a video about weak references! Especially about how they are implemented, and what ___weakref___ is for.

    • @Graham_Wideman
      @Graham_Wideman 2 года назад +5

      As I understand it, "weakref" is an overly elaborate term for simply a reference, that is, a pointer. But it has to be distinguished from conventional python references, which incorporate the reference counting mechanism that supports automatic garbage collection.

    • @alan5506
      @alan5506 2 года назад

      @@Graham_Wideman I haven't delved much into the details of python, but in Lua, a weak reference is a reference that is not counted for garbage collection. So, if something only has weak references, it is garbage collected.

    • @Graham_Wideman
      @Graham_Wideman 2 года назад

      @@alan5506 So you're saying Lua's use of the term "weak reference" is the same as what I wrote for Python?

    • @alan5506
      @alan5506 2 года назад +1

      ​@@Graham_Wideman Yes.

    • @LordMardur
      @LordMardur 2 года назад +1

      @@Graham_Wideman A weak reference is more than a pointer, because it needs to know, if the object still exists. Technically, you have the object itself and the reference counter (which is also an object managing the number of strong and weak references). The object is deleted when all strong references are gone. The reference counter is deleted when all (strong and weak) references are gone. Hence, a weak reference also "incorporates the reference counting mechanism" and is in fact a "smart" pointer, just like strong references.

  • @CircuitSacul
    @CircuitSacul 2 года назад +76

    WeakRef Video When

  • @Impatient_Ape
    @Impatient_Ape 2 года назад +182

    This sort of video is one of the reasons I like this channel. I greatly appreciate explanations that clarify confusing/subtle issues. It's a pedagogical approach I tried my best to implement when I used to teach, so I'm somewhat biased.

  • @skarfie123
    @skarfie123 2 года назад +32

    My favourite is __mifflin__()

  • @Chris-yw5is
    @Chris-yw5is 2 года назад +35

    coming from C++ I naturally tried to write clean up code in __del__ but sometimes the modules were already deleted which ended up being endlessly confusing
    Good video probably gonna save a lot of people from that specific headache

    • @alextrotta796
      @alextrotta796 Год назад +4

      In the exact same boat! As I've always said, deterministic destruction is a drug, once you have it you'll look for it everywhere.

    • @tonchozhelev
      @tonchozhelev 8 месяцев назад

      I learned programming with C++, but my career took me to higher level lenguages. Destructors are, easily, the feature of C++ I miss the most.

  • @rohansimon7410
    @rohansimon7410 2 года назад +35

    I didn't know __del__ was this hated. I have used it *once* before to create a scoped timer and it worked for that use case. Thanks for the insight on why I shouldn't lol.

  • @lawrencedoliveiro9104
    @lawrencedoliveiro9104 2 года назад +28

    6:10 I found another subtle case of this, where my ‗‗del‗‗ method had some local functions to do various related cleanup. Turned out that a direct reference from an inner function to the “self” argument of ‗‗del‗‗ would magically cause the object to be resurrected. I changed it to explicitly pass self as an argument to the inner routine, and that allowed the object to go away properly.
    Moral: reference cycles are subtle things ...

    • @tacticalassaultanteater9678
      @tacticalassaultanteater9678 2 года назад +1

      Closures are distinct objects and they hold counted references to their upvalues, _if and only if_ they continue to exist after __del__ is executed it makes sense that they resurrect the object. If they don't, that's probably an interpreter bug or a completely braindead spec because it implies that either the count is checked before the locals of __del__ are collected or resurrection depends on whether the count was modified, not whether it's greater than zero.

    • @lawrencedoliveiro9104
      @lawrencedoliveiro9104 2 года назад +1

      They were executing _during_ del.

    • @tacticalassaultanteater9678
      @tacticalassaultanteater9678 Год назад

      @@lawrencedoliveiro9104 This could very well be an interpreter bug then. Is it open source? Can you share a sample? I'd like to study this.

    • @tacticalassaultanteater9678
      @tacticalassaultanteater9678 Год назад

      @@lawrencedoliveiro9104 To be clear, if the only reference to the closure was within the locals of the calling function that weren't upvalues, it should not count as a reference cycle, because the locals of a function that aren't upvalues die when the function stops executing. The names of upvalues are known statically, so they aren't supposed to count as references to the entire set of locals but the specific one.

    • @lawrencedoliveiro9104
      @lawrencedoliveiro9104 Год назад

      @@tacticalassaultanteater9678 This was in my DBussy library.

  • @TigerWalts
    @TigerWalts 2 года назад +9

    Thanks for clarifying this. I now know that I have some code to clean up. I had my doubts that I was doing it right. It currently works as it is used but I can now see where it will fail.
    Funnily enough, I discounted context handling as unrequired but since adding `__enter__` and `__exit__` will cover the bases, I guess I'm going implement them.

  • @lawrencedoliveiro9104
    @lawrencedoliveiro9104 2 года назад +39

    2:26 Just a note that reference counting is a specific feature of the CPython implementation. There are some other Python implementations (such as those built on the Java VM) that do not do reference counting.

    • @Victor_Marius
      @Victor_Marius 2 года назад +3

      Probably the NullPointerException will hit you just as often as in Java

    • @codeofdestiny6820
      @codeofdestiny6820 2 года назад +6

      I think that in CPython it does both reference counting and the generational gc, but I could be wrong

    •  2 года назад +1

      @@codeofdestiny6820 yes, gc is for avoid reference cycle in cpython

    • @codeofdestiny6820
      @codeofdestiny6820 2 года назад

      @ I don't understand your answer, can you elaborate?

    •  2 года назад +4

      @@codeofdestiny6820 in the reference count there may be cases where A references B and B references A generating a reference cycle A B, depending on the implementation: 1 - the count of A never reaches zero, or 2 - it reaches zero but A and B leave the count however without deallocating memory and become inaccessible. some languages use strong and weak reference to solve this, A strong references B and B weak references A, A B (bad illustration in asc), when the count for A goes to zero, B will be automatically deallocated by have a weak reference to A (swift and also is posible in cpython but not is the default). cpython uses the garbage collector to solve this, because if A and B become inaccessible without deallocating memory, the garbage collector will solve why it knows the inaccessible objects (I don't know the details it but this is the idea)

  • @ZergyNaggafin
    @ZergyNaggafin 2 года назад +10

    You have the most informative python programming videos I've ever seen. Really love your content. I find tidbits like these very helpful. Thanks!

  • @TechSY730
    @TechSY730 2 года назад +24

    So __del__ is like finalize() in Java. (Sorry about the italics eating one of the underscore pairs; RUclips doesn't seem to provide a way to escape it...)
    Unpredictable, and strongly discouraged as a means of resource control or critical cleanup.
    Though may be usable as a fallback if the programmer forgets to close properly and that will result in a critical resource permanently lost within that execution. Or worse, silently incorrect behavior.
    In which case, you should first try to redesign so that isn't the case.
    If it is unavoidable, then at least raise a warning about the misuse or a stacktrace.
    (And also like finalizer, reference type objects are the superior solution for this anyways)

    • @ConstantlyDamaged
      @ConstantlyDamaged 2 года назад +3

      Slapping (self) on the end of the dunder name helps.
      __del__(self)

    • @minerscale
      @minerscale Год назад

      A programmer should never do something silent as a fallback for if they forget something. If they forget something the program should tell at the programmer loudly and throw an error.

    • @TechSY730
      @TechSY730 Год назад +1

      @@minerscale In pure best practices ideals, yes, I agree. Fail on it.
      However, there are plenty of people/organizations who won't follow/followed best practices. And won't (or won't be given time by their higher ups to) learn those best practices and refactor accordingly.
      If it is an existing code base you are adding this check to, then businesses will not like you "breaking" their application/stack, even if what is actually broken is their code.
      Or even if it is a new API, there is a good chance developers will find this strictness too annoying and/or time consuming. and instead chooses (or the higher-ups choose) some competing product. Instead of doing the right thing and fixing their own coding practices.
      It sucks, but here in the real business world, not accounting for or providing avenues to deal with less than ideal development circumstances (or outright laziness) will cause friction
      I think the best solution is configurable behavior, "fail", "warn", and maybe "ignore".
      Kind of like how "strict mode" works on Android (if set, raises exception if a resource cleanup is missed, else it just logs a warning)

  • @Galakyllz
    @Galakyllz 2 года назад +7

    I absolutely want to see a video about weakref: when it's the best situation to use it, when it will not solve my problem but I would assume that it would, and how to break it. Thanks!

  • @djl3009
    @djl3009 2 года назад +8

    This brings back memories of the RAII idiom (Resource Acquisition Is Initialisation) in C++. I remember (wrongly) assuming that Java finalisers worked in the same way as C++ destructors. Java's implementation of finalisers (finalize method) is very similar to what you describe here with __del__. The semantics of destructors in C++ was very simple and predictable -- much akin to context managers in Python.

    • @headlibrarian1996
      @headlibrarian1996 2 года назад +3

      We have some legacy C++ code with initialize/finalize methods. It’s disgusting, whoever wrote it was trying to write Java code in C++.

  • @lawrencedoliveiro9104
    @lawrencedoliveiro9104 2 года назад +13

    8:08 On Linux, it is possible to create temporary files that have no directory entry in the filesystem. That means they automatically disappear when closed.

    • @illegalsmirf
      @illegalsmirf 2 года назад

      How to do this? Please share

    • @lawrencedoliveiro9104
      @lawrencedoliveiro9104 2 года назад +1

      O_TMPFILE option to open(2).

    • @headlibrarian1996
      @headlibrarian1996 2 года назад +2

      @@illegalsmirf You can delete open files in Linux. You can read/write them, and pass open file descriptors to them to children.

  • @technowey
    @technowey 2 года назад +2

    LOL - The comment at the end about hitting the like button an odd number of times made me laugh.
    Great video. Thanks.

    • @mCoding
      @mCoding  2 года назад +1

      Glad you made it all the way!

  • @DuskyJoe
    @DuskyJoe 2 года назад +6

    Thanks, one more time, for putting time and effort into making these videos!
    I've taught Python for beginners myself, and made sure to make my students aware of your content ever since I found your channel myself.
    Since you asked: I'd be glad to see a follow up video on weak references sometime in the future.

  • @rongarza9488
    @rongarza9488 4 месяца назад

    "this" had always confused me, so I'm glad you said that "self" can be used like "this". However, I had started to use "for this_item in items:" So now I can accept either one, and "self" will work fine in Python.

  • @strandingstranger
    @strandingstranger 2 года назад

    Wow, this channel is pure gold. Thank you so much for your videos.

    • @mCoding
      @mCoding  2 года назад

      Glad you like them!

  • @thevalarauka101
    @thevalarauka101 9 месяцев назад +2

    when I was trying to make a custom class divide and the dunder just wouldn't work... I was so angry when I finally looked it up and found out it was __truediv__, instead of __div__. like just why

  • @CAMOBAP795
    @CAMOBAP795 2 года назад

    Thanks a lot for the video, the topic and explanations are awesome (as always)
    It will be really nice to have a video about garbage collector (primary algorythm, is it "tunable", native extensions and GC)

  • @christianloizou4463
    @christianloizou4463 Год назад +1

    Great video! I found this channel recently and have been binge watching videos, and have found myself learning so much. Can you do a video briefly going over all the __dunder__ methods that can be implemented in Python? I find myself using the same ones in almost every project I work on and wonder if there are any ways I can improve my code by using different / additional __dunder__ methods. Thanks!

    • @mCoding
      @mCoding  Год назад +2

      Working on one already!

  • @mustafamotiwala2335
    @mustafamotiwala2335 2 года назад +3

    would definitely like a weakref video :)

  • @mystisification
    @mystisification 2 года назад

    Awesome content, thanks James!

  • @hicoop
    @hicoop 2 года назад +9

    Every time I think I know everything about python, mCoding finds another hidden feature I haven't heard about. Please do a video on the nonlocal keyword!

  • @KeyserTheRedBeard
    @KeyserTheRedBeard 2 года назад +1

    sweet upload mCoding. I broke the thumbs up on your video. Always keep up the very good work.

  • @dalerrahimov2387
    @dalerrahimov2387 Год назад

    Very good to know. I have been using __del__ for a long time as distructors

  • @sweetdreamsdotexe
    @sweetdreamsdotexe Год назад

    I wasn't sure of what dunder method was the most annoying before this video. I am now. I'm also relieved that you discussed options to it in the end, my inner peace would be destroyed if you didn't so thanks for that.

  • @sanderbos4243
    @sanderbos4243 2 года назад

    Awesome video, thanks!

  • @AlexanderWhillas
    @AlexanderWhillas 2 года назад

    First "click-bait" title I've seen for programming related content I've seen :D

  • @robertbrummayer4908
    @robertbrummayer4908 2 года назад

    Excellent video as usual

  • @t0prar
    @t0prar Год назад +1

    When a Python video triggers your C++ PTSD ...

  • @bdafeesh
    @bdafeesh 2 года назад +1

    Wow I've just never thought about __del__. On my teams we tend to agree to not overload any dunders except for new and repr. Thanks for making this video letting us know of the hole :o
    Edit: I still think __del__ COULD be useful in very niche instances, but overall it needs to be insanely justified.

  • @alagaika8515
    @alagaika8515 2 года назад

    IIRC, the CPython GC detects reference cycles, but then drops all involved objects without calling their dunder del methods - after all, I might expect to be able to use self.parent in the child's dunder del, and vice versa, so in which order should they be cleaned up?

  • @MrRyanroberson1
    @MrRyanroberson1 2 года назад +1

    with the weakref module, doesn't this also mean there should be some kind of guideline about not implementing cyclic references directly? such as it being formally recommended that if children need to refer to their parents, that they use a weakref for it? i suppose this also has problems because if a child needs to refer to the parent then any additional references to the child will necessarily break if the parent vanishes, so they would need to have some sort of exception behavior where they act like "None" when they discover their parents are None

  • @voodooman08
    @voodooman08 2 года назад

    Can you tell about dunders __reduce__ and __reduce_ex__? I guess they are old and used for serialization, django's sources customize them for some structures.

  • @quintencabo
    @quintencabo 2 года назад

    Great video! Can you make a video about yield from

  • @NicolasChanCSY
    @NicolasChanCSY 2 года назад +1

    Not related to this video, but do you have any recommendations for PyCon US 2022 videos?

    • @mCoding
      @mCoding  2 года назад +1

      Watch the new typing stuff and the one on the history and direction of the match statement!

  • @japedr
    @japedr 2 года назад +1

    7:05 Could this potential issue be avoided with a "import shutil" line to ensure it is loaded, or is that still problematic somehow?

    • @mCoding
      @mCoding  2 года назад +4

      Excellent idea, but unfortunately trying to import a module during interpreter shutdown is likely to cause a crash or other badness for ... "reasons". You also shouldn't attempt to start new threads or subprocesses.

    • @lawrencedoliveiro9104
      @lawrencedoliveiro9104 2 года назад +1

      My solution to this is to register an atexit function in the containing module that goes through all classes that have potentially troublesome ‗‗del‗‗ methods and delete them from the class. E.g.
      def _atexit() :
      for cłass in Connection, Server, PreallocatedSend, Message, PendingCall, Error, AddressEntries :
      delattr(cłass, "__del__")
      ♯end for
      ♯end _atexit
      atexit.register(_atexit)
      Instances that disappear during normal program operation get cleaned up as usual; ones that are left at program termination are not.

  • @ConstantlyDamaged
    @ConstantlyDamaged 2 года назад +4

    Ha! I saw this one coming. The best part about the unpredictability of __del__(self) is when you need to run async code cleanup.
    Just don't. Find another way to work.

  • @danielalvesldiniz
    @danielalvesldiniz Год назад

    i believe the builtin lib atexit is also a good way to run cleanup code, if it's code intended to run once right before the interpreter exits. you `atexit.register(foobar)` to schedule `foobar` to be run on the process' shutdown. some other builtin libs use atexit like this

  • @yellingintothewind
    @yellingintothewind 10 месяцев назад

    CPython isn't guaranteed to run the destructor when the refcount hits 0. If the object is marked "immortal" (None, True, False, and the like), then even hitting 0 doesn't do anything.
    If the refcount hits 0, then it invokes tp_dealloc, as provided by the C-struct holding the python data. It is possible for _that_ to do nothing, but only if you are using types derived from some extension library.

  • @blankRiot96
    @blankRiot96 Год назад

    I'd love to learn more about weak references

  • @ludo3941
    @ludo3941 2 года назад

    Do you have a video explaining what's CPython?

  • @heistberg6733
    @heistberg6733 2 года назад

    At first I used the __del__ method to free resources but stop using it because it was called twice frequently, so I replaced it with atexit. What is the difference between weakref and atexit?

    • @unfriedrice7865
      @unfriedrice7865 9 месяцев назад

      It turns out weakref uses atexit under the hood ^^ so not much probably

  • @LordMardur
    @LordMardur 2 года назад +2

    Relying on destructors is generally a bad idea in garbage collected languages. Same goes with Java, where you can never be sure any destructor runs and objects can be resurrected. This is odd behavior, if you are coming from C++, which makes strong guarantees about object lifetime and destruction (see RAII). For cleanup code, like deleting temp files, I usually use atexit. Finalizers seem to be an interesting alternative, when they handle being called directly before exit.

    • @mCoding
      @mCoding  2 года назад

      Agreed and I know exactly what you mean coming from C++. Btw weakref finalize uses atexit under the hood.

  • @DrDeuteron
    @DrDeuteron 10 месяцев назад

    do you prefer self.__class__ over type(self), and if so: why?

  • @epiczoom
    @epiczoom 2 года назад

    So basically __del__ can prevent memory corruption bugs that pops up every now and then in JS. (It is being called when the object is removed from memory)

  • @rb1471
    @rb1471 Год назад

    What cleans the finalizer?

  • @izzikora6751
    @izzikora6751 Год назад

    So is the conclusion of this video that there are no circumstances under which one should ever use dunder-del? I know the creator here did specify a number of situations that could go wrong, but are there *any* circumstances under which one might want to use one?

  • @dexio85
    @dexio85 Год назад +1

    And people used to complain about C++ destructors....

  • @CSDragon
    @CSDragon Год назад

    As a java programmer, what on earth is a Dunder method? Like, from The Office?

  • @dixonstroi
    @dixonstroi 2 года назад

    "Dude, you might not get a __del__"

  • @dalekman8945
    @dalekman8945 2 года назад

    Does anyone know what the other versions of 'cpython' would be? I've never heard of that term before.

    • @maxsteffey6521
      @maxsteffey6521 2 года назад

      He means Cython I’d guess

    • @deimuader
      @deimuader 2 года назад

      I think he meant other implementations of python per se.
      CPython is an individual reference implementation, but there are a lot of other implementations, like IronPython, PyPy, Jython and less known ones.

    • @dalekman8945
      @dalekman8945 2 года назад

      @@deimuader ok thanks bro! Yea i guess I had always heard terms like PyPy and Jython before, but never actually connected it to what they really were. The fact that most python implementations are Cython makes a lot of sense as to why python can have some nice bindings with C. Thanks for the responses yall!

  • @johnrussell6971
    @johnrussell6971 Год назад +1

    Whoever wrote __del__ must...(ahem) a dunder head!
    ...I'll see myself out

  • @aflous
    @aflous 2 года назад +3

    finalizers are idempotent!

    • @mCoding
      @mCoding  2 года назад +1

      I made sure to avoid using a math word in a programming video but you're absolutely right. Idempotent is the technically best way to describe them (or how they _should_ be).

  • @zanehannan5306
    @zanehannan5306 2 года назад

    After using rust for so long, and particularly Arc and Rc (ref counting stuff), del reads exactly like the Arc::drop non-inlined Arc::drop_slow.

  • @Graham_Wideman
    @Graham_Wideman 2 года назад

    I appreciate being alerted to the issues, but this presentation would be more complete if it told what a finalizer actually does. As it stands, it appears that sprinkling finalizer dust over your code in random places casts some sort of protective spell on it that makes it all good.

    • @landsgevaer
      @landsgevaer 2 года назад +1

      At the end he does ask to comment if you want to know more about weakrefs, so I guess that was his cliffhanger and you would like to see that follow-up...
      😉

    • @mCoding
      @mCoding  2 года назад

      A finalizer is for doing anything you need to do right before an object is garbage collected.

    • @Graham_Wideman
      @Graham_Wideman 2 года назад

      @@mCoding "A finalizer is for..." Yes, that much is obvious from the name. But in this video we don't seem to see where that "doing anything" is actually defined and how it gets invoked. I know, I could RTFM... just that it seemed like rather a hole in this otherwise nice story.

  • @CottidaeSEA
    @CottidaeSEA Год назад

    The example shown at 4:00 should in my opinion throw an exception. Circular references are poison and should never be allowed.

  • @marcelguinhos9022
    @marcelguinhos9022 2 года назад +1

    __ del __ is pretty useful for writing ctypes ffi/library wrappers

  • @zacharyreilly7307
    @zacharyreilly7307 2 года назад

    I want to see a video about weak references

  • @redcrafterlppa303
    @redcrafterlppa303 Год назад

    This whole thing is a problem all gc languages at some point face. Java's finalize() method is equivalent to __del__. Java also has try(..) blocks which are equivalent to with.. as.. : java also have the cleaner class which is equivalent to finalizers in python. This shows that even though java and python have little in common besides being gc languages they still share this exact problem. Java actually is in process of removing the finalize() method (__del__) in the near future.

  • @MasterHigure
    @MasterHigure 2 года назад

    At 4:20 (heh), you say in the comment that the refcount is 0!, but it's not. It's actually 0.

  • @aloysiuskurnia7643
    @aloysiuskurnia7643 Год назад

    my least favorite dunder that i actually use? Well I dunno, but I kinda dislike the separation of repr and str. I usually just went straight to __str__, then just slapping def __repr__(): return str(this).

  • @YourCRTube
    @YourCRTube Год назад

    So, what is del for then?

  • @wrathofainz
    @wrathofainz Год назад

    I have never used that keyword and I am not sure why I would.

  • @aaronm6675
    @aaronm6675 2 года назад +2

    Dunders!!

  • @DuarteMolha
    @DuarteMolha 2 года назад

    Everytime I think I am getting good at python I see your videos and realise how much I don't know.

  • @b4ttlemast0r
    @b4ttlemast0r Год назад

    so it's like a desctructor but doesn't work well

  • @thomasbates9189
    @thomasbates9189 2 года назад

    Okay, just wow! I didn't know any of that. I always thought that "del x" called __del__

  • @Bondrewd_21
    @Bondrewd_21 2 года назад

    3:20
    As far as I know, this is outdated documentation. Now it is always called at the end of the program when all objects are destroyed.

  • @slava6105
    @slava6105 2 года назад +2

    x.children = [y]
    y.parent = x
    that's what weakrefs needed for

    • @mCoding
      @mCoding  2 года назад +2

      Indeed weakrefs can break this cycle, although CPython 3.4+ is able to detect and delete these cycles so it is not necessary. Though i will certainly talk about this if i do a weakref video!

    • @lawrencedoliveiro9104
      @lawrencedoliveiro9104 2 года назад

      Weak refs are useful.
      But why does Java need _three_ different kinds of weak refs, when Python can make do with one?

    • @slava6105
      @slava6105 2 года назад

      @@lawrencedoliveiro9104 I don't know exactly, but Java in comparison with Python has GC (Garbage Collector) that defines behaviour of working with each type of reference (Soft/Weak/Phantom). This behaviour can also rely on jvm realisation (e.g., _as I know or think_, Hotspot uses timestamps for SoftReference and IBM VM counts how many gc calls this ref survived).
      I didn't find any useful material to put here, so I wish you good luck with understanding refs in Java

  • @andrewglick6279
    @andrewglick6279 2 года назад

    I'm enjoying reading through all the comments of people trying various ways to type ___dunder___ methods without RUclips messing with the formatting 😂 (Fitting that it took me 3 attempts to get this comment to format like this)

  • @LeeSpork
    @LeeSpork 2 года назад +1

    The dunder blunder

  • @jeffreyhuang3249
    @jeffreyhuang3249 2 года назад

    My prediction would’ve been get_attribute (not to be confused with get_attr which is amazing)

  • @Mutual_Information
    @Mutual_Information Год назад +1

    Lol i didn’t hate __del__.. but now I do

  • @p1geon45
    @p1geon45 Год назад

    i like how u have a reference cycle in "parents" and "children"... *sweet home alabama*
    jkjk

  • @quintrankid8045
    @quintrankid8045 2 года назад

    Weakref video please.

  • @greg4367
    @greg4367 2 года назад

    Every time I even consider leaving my much beloved C and using Python I run across another reason to just go back into my glorious C shell. If a program wants/needs to delete a THING, then delete the thing, and quit expecting the compiler or OS to hold your bloody hand. But, then again, still don't see the point in moving from C to C++, nor does that guy who wrote the Linux Kernel.

    • @alextrotta796
      @alextrotta796 Год назад

      The whole idea is that it eliminates a whole class of errors. Think about it, if you have an API where you create a thing, and you need to destroy that thing (else get a resource leak, or maybe other bad things happen), and you expect the users of the API to clean it up... wouldn't it just be easier if the language had a built in feature to make sure you can never get that wrong? It lowers the complexity of APIs, because there is no additional function to clean things up, it's tied to the object and (more or less) never gets called manually) Now you just declare a thing, and when you're done with it the cleanup code gets run, either via garbage collection + a callback, or in C++ you have RAII, which in turn is the basis for OBRM in Rust - the latter two being completely deterministic.
      It is the single feature from C++ that I love so much that I could never use C, because it doesn't have that.

  • @htetaung04
    @htetaung04 Год назад

    I love Dunder Mifflin. Does that count?

    • @mCoding
      @mCoding  Год назад

      It would only count if you disliked it!

  • @yash1152
    @yash1152 11 месяцев назад

    3:09 > _"circumstantial"_
    nice term for such cases.
    not impliable...

  • @Ba_Dashi
    @Ba_Dashi 2 года назад

    Comparing to other languages that include cleanup code(defer in go, deconstructors in c++), the caveats for dunder del seem all very reasonable. You SHOULDN'T be doing long running operations, opening files or reviving variables in cleanup methods. That's just inviting trouble! I know it's usually a bad argument to say "the programmer should do the Right Thing" for language features, but on an implicit cleanup method like dunder del it's one of the places that there's only so much the compiler/interpreter can do. At best, python could warn against certain patterns but they could always be circumvented.
    Tbh if you are relying on such implicit behavior for cleaning up, I'd say you need to rethink your code(like this video proposes), but I don't see any reason to hate dunder del because all arguments "against" it are pretty obvious for anyone who has ever dealt with memory management(and if you haven't, you're probably not the target for dunder del in the first place...)

    • @Ba_Dashi
      @Ba_Dashi 2 года назад

      As an addendum: Go's _defer_ can actually be used for all the things above, since Go has a different type of garbage collector and, as a compiled language, it actually just rewrites your function to execute _defer_ at the end of it instead of at the point it was called, no different than try/finally statements. Of course, Go has a runtime.SetFinalizer which is more closely related to Python's dunder del, but that one is far more explicit and doesn't attach itself to every instance of a struct(though technically you could write a constructor to do just that). The exact same caveats as dunder del applies to it.

  • @sharkinahat
    @sharkinahat 2 года назад

    _ _call_ _ and _ _new_ _ would be in my top 3, but _ _del_ _ is the king of Dutch dunders (not be obvious at first unless you're Dutch).

  • @andytheodorko9874
    @andytheodorko9874 2 года назад +1

    repr is awesome

    • @mCoding
      @mCoding  2 года назад

      If you know you know!

  • @PavloPravdiukov
    @PavloPravdiukov Год назад

    Yay for mentioning context managers! Nay for not calling them "context managers"...

    • @mCoding
      @mCoding  Год назад

      I mean... pretty sure someone who searches for "with statement" will end up at the right place, and it is arguably clearer what a "with statement" is referring to than a "context manager" to someone who doesn't already know what with statements and context managers are and how they are related.

  • @mr.bulldops7692
    @mr.bulldops7692 2 года назад

    Weak ref vid, plz!!!

  • @ludo3941
    @ludo3941 2 года назад +1

    slapped 3 times

  • @diamonddemon7612
    @diamonddemon7612 Год назад

    who was the dunderhead who added this?

  • @johnwt7333
    @johnwt7333 2 года назад

    Dunder Mifflin

  • @chriskeo392
    @chriskeo392 2 года назад +2

    can't we avoid all of this with dataclasses package?

    • @lawrencedoliveiro9104
      @lawrencedoliveiro9104 2 года назад

      This mechanism is still needed for things like wrappers for non-Python libraries. They tend to expect explicit calls to dispose of objects, and it’s nice if the Python user doesn’t have to worry about such things. It takes a certain amount of mechanism to ensure this happens reliably.

  • @Joooooooooooosh
    @Joooooooooooosh Год назад

    Laughs in COM.

  • @ianyourgod
    @ianyourgod 2 года назад

    i use del :)

  • @GertCuykens
    @GertCuykens Год назад

    Ok you convinced me it's bad, but why don't they deprecate it?

  • @MrTrilbe
    @MrTrilbe Год назад

    I have to say my favorite one is " if __cats__ > 1 then __ __ __ __cats__ == 'ho!'"

  • @xxlarrytfvwxx9531
    @xxlarrytfvwxx9531 2 года назад +1

    What does the assert keyword do?

    • @Boringpenguin
      @Boringpenguin 2 года назад +10

      to perform an assertion on a condition, an AssertionError would be raised if the condition evaluates to False.
      It is really useful when you're writing tests

    • @nathanbrown2640
      @nathanbrown2640 2 года назад +1

      You can add a message to that Assertion Error by providing a second argument, e.g
      assert a!=b, "Oh dear - a shouldn't equal b"

    • @user-he4ef9br7z
      @user-he4ef9br7z 2 года назад

      Throws an error if a condition is false.

    • @deimuader
      @deimuader 2 года назад +1

      Be careful with asserts, as they can be optimized away if you start a script with python -O script.py.

  • @MrFluteboy1980
    @MrFluteboy1980 2 года назад +2

    I know that this will be basically considered blasphemy, but I wish you did videos on PHP. I don't even use python! I just enjoy your videos!

    • @mCoding
      @mCoding  2 года назад +3

      Maybe one day... not today though!

  • @piotrmazgaj
    @piotrmazgaj Год назад

    '__setattribute__' because it desen't exist, which makes me crazy as you get: '__get__', '__set__', '__getattr__', '__setattr__', '__getattribute__' and.... None

  • @TheForgedReality
    @TheForgedReality 2 года назад

    Watching your videos just proves to myself that I don't know anything. 🤦

  • @danibarack552
    @danibarack552 Год назад

    the worst is the word 'dunder' itself

  • @markeroo9297
    @markeroo9297 2 года назад

    If __del__ is so unreliable, why does it even exist? Who uses it?

  • @alexandertownsend3291
    @alexandertownsend3291 Год назад

    C Python? Wait there is more than 1 Python?