On Wed, Dec 10, 2014 at 7:15 PM, Steven D'Aprano <st...@pearwood.info> wrote:
> On Wed, 10 Dec 2014 18:18:44 -0800, Rustom Mody wrote: > > > > And going the other way -- no defs only lambdas its this: > > > > > >>>> f = lambda : (lambda x= {}: x) > >>>> f()() is f()() > > False > >>>> d = f() > >>>> d() is d() > > True > >>>> > >>>> > > > > But I have a different question -- can this be demonstrated without the > > 'is'? > > > Can *what* be demonstrated? That the functions returned are different > objects, or that the dicts are different objects? Both? Something else? > > Using "is" you are demonstrating that calling the function twice returns > two distinct objects. That is the purpose of "is", to compare object > identity. Without "is", you can compare object IDs directly: > > id(f()()) == id(f()()) > > but that's ugly and less efficient. Using "is" is the more idiomatic and > natural way to do this. > In CPython, that does not work, as the dictionary will be garbage collected after each call to id: >>> f = lambda : (lambda x= {}: x) >>> f()() is f()() False >>> id(f()()) == id(f()()) True > > Other than that, you could do something to demonstrate the consequences > of the two values being distinct objects: > > a = f()() # Call twice to get a dict. > b = f()() > a['key'] = 23 > b['key'] # raises KeyError > > > or > > a = f() # Call once to get a function. > b = f() > a.attribute = 23 > b.attribute # raises AttributeError > > > Or you could inspect the byte-code of f and try to understand it. > > Another way would be to to demonstrate the behavior, without using is, would be to use a global counter variable: a = 1 def f(): global a def g(b=[a]): return b a += 1 return g >>> f()() [1] >>> f()() [2] >>> a = f() >>> a() [3] >>> a() [3] >>> b = f() >>> b() [4] >>> a() [3]
-- https://mail.python.org/mailman/listinfo/python-list