You also need to remember to use RAII, and that always requires creating a class. You also need to get RAII right, where as Python's with is implemented for you.
Also there's no mention about the fact that Java forces you to check for exceptions (well not for unchecked ones, but those should not be fatal, and I never really got their idea). You can't forget the try-catch.
The library author needs to remember to use RAII, but the client doesn't need to remember anything (as in his examples). Whereas with 'with' it's the opposite - the client has to remember to use it.
But that brings up the non-deterministic point the author makes. You can't know when the object will be garbage collected. It could be a long time from now, or never if you get an unexpected deadlock.
So when does it gets decremented? When the variable gets out of scope, or voluntarily when you call 'del', just as in C++ or D. The difference lies in the notion of scope which is just different than of the one of C/C++/D/Java/C#.
Example:
from __future__ import print_function
class Foo:
def __init__(self, text):
self.text = text
def __del__(self):
print("deleting %s" % self)
def __str__(self):
return ("%r(%s)" % (self,self.text))
def bar():
if True:
print("+scope 1 in bar")
f = Foo("in bar")
print("-scope 1 in bar")
if True:
print("+scope 1")
bar()
print("bar quit")
if True:
print("+scope 2")
f = Foo("global")
print("-scope 2")
print(f)
print("-scope 1")
will output:
+scope 1
+scope 1 in bar
-scope 1 in bar
deleting <__main__.Foo instance at 0x1004d4a70>(in bar)
bar quit
+scope 2
-scope 2
<__main__.Foo instance at 0x1004d4a70>(global)
-scope 1
deleting <__main__.Foo instance at 0x1004d4a70>(global)
By now you have noticed that the scope is function-wide (or module-wide for global code).
So you can write the exact same code that he wrote in C++ in python and it would work the exact same way, and it doesn't create the Java dispose() mess of slide 12.
There is a twist though. Exceptions. Say you have an uncaught exception raised in bar(), then the Foo object created in bar() will be referenced in the stack frame of the exception, which belongs to the caller of bar(), so the Foo object reference count will drop to zero only after the caller scope closes.
and calling it in place of bar() after "+scope 1", while raising any exception in bar().
If you want to override this behavior you can just as well call del when you want to get rid of the object, which is just as forgettable as adding 'scope' to variables declarations in the author's almighty D.
However, to be outrageously precise about it, this behavior is the one of CPython's GC, and should not be relied on as specified by the documentation (beginning of http://docs.python.org/reference/datamodel.html)
Objects are never explicitly destroyed; however, when they become unreachable they may be garbage-collected. An implementation is allowed to postpone garbage collection or omit it altogether — it is a matter of implementation quality how garbage collection is implemented, as long as no objects are collected that are still reachable.
CPython implementation detail: CPython currently uses a reference-counting scheme with (optional) delayed detection of cyclically linked garbage, which collects most objects as soon as they become unreachable, but is not guaranteed to collect garbage containing circular references. See the documentation of the gc module for information on controlling the collection of cyclic garbage. Other implementations act differently and CPython may change. Do not depend on immediate finalization of objects when they become unreachable (ex: always close files).
As the Zen of Python says: explicit is better than implicit and in the face of ambiguity, refuse the temptation to guess. Hence the decision Python (IMHO rightfully) made about being explicit about it, and allow whatever current of future memory management scheme to be appropriate and forward compatible. This is already happening with PyPy (http://pypy.org/compat.html).
Also there's no mention about the fact that Java forces you to check for exceptions (well not for unchecked ones, but those should not be fatal, and I never really got their idea). You can't forget the try-catch.