On Sun, 19 Aug 2018 11:43:44 +0300, Marko Rauhamaa wrote: > Steven D'Aprano <steve+comp.lang.pyt...@pearwood.info>: > >> On Sun, 19 Aug 2018 00:11:30 +0300, Marko Rauhamaa wrote: >> >>> In Python programming, I mostly run into closures through inner >>> classes (as in Java). >> >> Inner classes aren't closures. > > At least some of the methods of inner classes are closures (or there > would be no point to an inner class).
(1) Ironically, the only times I've used an inner class, its methods were not closures. So yes, there are sometimes uses for inner classes that don't include closures. There's an example in the argparse module in the standard library, and it too has no closures. (2) Whether or not the methods of an inner class are closures depends on the methods, not the fact that it is an inner class. There are no closures here: class Outer: class Inner: ... no matter what methods Inner has. Nor is this a closure: class Outer: def method(self): class Inner: def spam(self): return self.eggs return Inner since the spam method doesn't close over any of the variables in method. You made a vague comment about inner classes being equivalent to closures in some unknown fashion, but inner classes are not themselves closures, and the methods of inner classes are not necessarily closures. >> Its also quite expensive to be populating your application with lots of >> classes used only once each, which is a common pitfall when using inner >> classes. Memory is cheap, but it's not so cheap that we ought to just >> profligately waste it needlessly. > > That is a completely separate question. It wasn't a question, it was an observation. > There's is no a-priori reason for inner classes to be wasteful; Not in languages where classes are declared statically and built at compile-time, no. But in a language like Python where classes are executable statements that are built at run time, like constructing any other mutable object, it is very easy to use them badly and waste memory. This doesn't look harmful: def func(x): class Record: def __init__(self, a): self.a = a return Record(x) but it is. You might not like that design, but it is part of Python's execution model and whether you like it or not you have to deal with the consequences :-) > they > have been part and parcel of Java programming from its early days, and > Java is widely used for high-performance applications. https://dirtsimple.org/2004/12/python-is-not-java.html > CPython does use memory quite liberally. I don't mind that as > expressivity beats performance in 99% of programming tasks. Fair enough, but in the example I showed above, the practical effect is to increase the de facto size of the objects returned by func() twenty times. And fragment memory as well. In a long-lived application where you are calling func() a lot, and saving the objects, it all adds up. >>> populating an object with fields (methods) in a loop is very rarely a >>> good idea. >> >> Of course it is *rarely* a good idea > > So no dispute then. Isn't there? Then why are you disagreeing with me about the exceptional cases where it *is* a good idea? -- Steven D'Aprano "Ever since I learned about confirmation bias, I've been seeing it everywhere." -- Jon Ronson -- https://mail.python.org/mailman/listinfo/python-list