Path: csiph.com!v102.xanadu-bbs.net!xanadu-bbs.net!feeder.erje.net!eu.feeder.erje.net!newsfeed.xs4all.nl!newsfeed1.news.xs4all.nl!xs4all!post.news.xs4all.nl!not-for-mail Return-Path: X-Original-To: python-list@python.org Delivered-To: python-list@mail.python.org X-Spam-Status: OK 0.009 X-Spam-Evidence: '*H*': 0.98; '*S*': 0.00; 'expressions': 0.07; 'subject:Getting': 0.07; 'library?': 0.09; 'cc:addr:python-list': 0.11; 'def': 0.12; 'defaultdict': 0.16; 'lambda': 0.16; 'received:74.55.86': 0.16; 'received:74.55.86.74': 0.16; 'received:smtp.webfaction.com': 0.16; 'received:webfaction.com': 0.16; 'repr': 0.16; 'values?': 0.16; 'wrote:': 0.18; 'cc:addr:python.org': 0.22; 'print': 0.22; 'this?': 0.23; 'header :User-Agent:1': 0.23; 'skip:c 70': 0.24; 'cc:2**0': 0.24; 'cc:no real name:2**0': 0.24; 'header:In-Reply-To:1': 0.27; "doesn't": 0.30; 'skip:( 20': 0.30; 'class': 0.32; 'skip:c 30': 0.32; 'reader': 0.33; 'skip:_ 10': 0.34; 'skip:d 20': 0.34; 'but': 0.35; 'there': 0.35; 'false': 0.36; 'possible': 0.36; 'subject:?': 0.36; 'clear': 0.37; 'skip:& 10': 0.38; 'pm,': 0.38; 'anything': 0.39; 'does': 0.39; 'most': 0.60; 'to:addr:gmail.com': 0.65; 'default': 0.69; 'confusing': 0.84; 'd[1]': 0.84; 'd[2]': 0.84 Date: Wed, 29 May 2013 14:10:58 -0400 From: Ned Batchelder User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:17.0) Gecko/20130509 Thunderbird/17.0.6 MIME-Version: 1.0 To: Croepha Subject: Re: Getting a callable for any value? References: In-Reply-To: Content-Type: multipart/alternative; boundary="------------040009050607080704070309" Cc: python-list@python.org X-BeenThere: python-list@python.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: General discussion list for the Python programming language List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Newsgroups: comp.lang.python Message-ID: Lines: 165 NNTP-Posting-Host: 2001:888:2000:d::a6 X-Trace: 1369851066 news.xs4all.nl 15947 [2001:888:2000:d::a6]:37332 X-Complaints-To: abuse@xs4all.nl Xref: csiph.com comp.lang.python:46399 This is a multi-part message in MIME format. --------------040009050607080704070309 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit On 5/29/2013 1:46 PM, Croepha wrote: > Is there anything like this in the standard library? > > class AnyFactory(object): > def __init__(self, anything): > self.product = anything > def __call__(self): > return self.product > def __repr__(self): > return "%s.%s(%r)" % (self.__class__.__module__, > self.__class__.__name__, self.product) > > my use case is: > collections.defaultdict(AnyFactory(collections.defaultdict(AnyFactory(None)))) > > And I think lambda expressions are not preferable... > It's not clear to me that this does what you want. Won't your defaultdict use the same defaultdict for all of its default values? This is hard to describe in English but: d = collections.defaultdict(AnyFactory(collections.defaultdict(AnyFactory(None)))) d[1][1] = 1 d[2][2] = 2 print d[1] #-> defaultdict(__main__.AnyFactory(None), {1: 1, 2: 2}) print d[1] is d[2] #-> True It might not be possible to get this right without lambdas: d = collections.defaultdict(lambda: collections.defaultdict(lambda: None)) d[1][1] = 1 d[2][2] = 2 print d[1] #-> defaultdict( at 0x02091D70>, {1: 1}) print d[1] is d[2] #-> False --Ned. > I found itertools.repeat(anything).next and > functools.partial(copy.copy, anything) > > but both of those don't repr well... and are confusing... > > I think AnyFactory is the most readable, but is confusing if the > reader doesn't know what it is, am I missing a standard implementation > of this? > > > --------------040009050607080704070309 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit On 5/29/2013 1:46 PM, Croepha wrote:
Is there anything like this in the standard library?

class AnyFactory(object):
def __init__(self, anything):
self.product = anything
def __call__(self):
return self.product
def __repr__(self):
return "%s.%s(%r)" % (self.__class__.__module__, self.__class__.__name__, self.product)

my use case is: collections.defaultdict(AnyFactory(collections.defaultdict(AnyFactory(None))))

And I think lambda expressions are not preferable...


It's not clear to me that this does what you want.  Won't your defaultdict use the same defaultdict for all of its default values?  This is hard to describe in English but:
    d = collections.defaultdict(AnyFactory(collections.defaultdict(AnyFactory(None))))

    d[1][1] = 1
    d[2][2] = 2

    print d[1]
    #->  defaultdict(__main__.AnyFactory(None), {1: 1, 2: 2})
    print d[1] is d[2]
    #->  True
It might not be possible to get this right without lambdas:
    d = collections.defaultdict(lambda: collections.defaultdict(lambda: None))

    d[1][1] = 1
    d[2][2] = 2

    print d[1]
    #->  defaultdict(<function <lambda> at 0x02091D70>, {1: 1})
    print d[1] is d[2]
    #->  False

--Ned.

I found itertools.repeat(anything).next and functools.partial(copy.copy, anything)

but both of those don't repr well... and are confusing...  

I think AnyFactory is the most readable, but is confusing if the reader doesn't know what it is, am I missing a standard implementation of this?




--------------040009050607080704070309--