Path: csiph.com!usenet.pasdenom.info!weretis.net!feeder1.news.weretis.net!feeder.erje.net!newsfeed.xs4all.nl!newsfeed5.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.000 X-Spam-Evidence: '*H*': 1.00; '*S*': 0.00; 'syntax': 0.04; 'argument': 0.05; 'case.': 0.05; 'root': 0.05; 'things.': 0.05; 'def': 0.06; 'escape': 0.07; 'expressions': 0.07; 'feature.': 0.07; 'function,': 0.07; 'indices': 0.07; 'processing.': 0.07; 'strings.': 0.07; 'suppose': 0.07; 'python': 0.09; '*is*': 0.09; '3),': 0.09; 'curve': 0.09; 'dict': 0.09; 'format:': 0.09; 'mode.': 0.09; 'operator,': 0.09; 'page?': 0.09; 'skip:k 40': 0.09; 'spelled': 0.09; 'subject:string': 0.09; 'symbols': 0.09; 'yeah,': 0.09; '(in': 0.11; 'subject:python': 0.11; '>>>': 0.14; 'essential': 0.14; 'to:name:python-list@python.org': 0.14; '1),': 0.16; '2),': 0.16; 'arguments:': 0.16; 'but\xa0': 0.16; 'dictionary.': 0.16; 'efficiently.': 0.16; 'eval': 0.16; 'expression.': 0.16; 'expressions,': 0.16; 'expressions.': 0.16; 'from:addr:lanyjie': 0.16; 'from:name:yingjie lan': 0.16; 'magic': 0.16; 'printf': 0.16; 'received:124.205': 0.16; 'redundancy': 0.16; 'reply-to:addr:lanyjie': 0.16; 'reply-to:name:yingjie lan': 0.16; 'someone,': 0.16; 'suggested,': 0.16; 'suppose.': 0.16; 'sure.': 0.16; 'winner.': 0.16; 'yingjie': 0.16; '{0}': 0.16; 'language': 0.16; 'string,': 0.17; 'examples': 0.18; '(or': 0.18; 'code,': 0.19; 'string': 0.19; 'all,': 0.21; 'element': 0.21; 'explicit': 0.21; 'keys': 0.21; 'maybe': 0.22; 'header:In-Reply- To:1': 0.22; 'matching': 0.23; 'case,': 0.23; 'thus': 0.23; 'together.': 0.23; 'that.': 0.24; 'pass': 0.24; 'class': 0.25; 'cheers,': 0.26; 'function': 0.26; 'seems': 0.27; 'common': 0.28; 'values': 0.28; 'consequence': 0.28; 'once,': 0.28; 'once.': 0.28; 'received:98.138.87': 0.28; 'str': 0.28; 'subject:skip:i 10': 0.28; 'though.': 0.28; 'yes.': 0.28; 'reply-to:addr:yahoo.com': 0.28; "i'm": 0.29; 'embedded': 0.30; 'query': 0.30; 'initial': 0.30; '(and': 0.30; 'point': 0.31; 'array': 0.31; 'generally': 0.31; 'itself': 0.31; 'passed': 0.31; 'requirement': 0.31; 'thanks!': 0.31; "can't": 0.32; "aren't": 0.32; 'like:': 0.32; 'probably': 0.32; 'could': 0.32; 'actual': 0.33; 'really': 0.33; 'handle': 0.33; 'something': 0.34; 'mapping': 0.34; 'mean': 0.34; 'to:addr:python-list': 0.35; 'done': 0.35; 'things': 0.35; 'useful': 0.35; 'should': 0.35; 'end': 0.35; 'paying': 0.35; 'quickly': 0.35; "skip:' 20": 0.35; 'skip:m 40': 0.35; 'there': 0.36; 'does': 0.36; 'takes': 0.36; 'them,': 0.36; 'doing': 0.36; 'legal': 0.64; 'header:Reply-To:1': 0.67; 'taking': 0.68; 'hey,': 0.72; 'everybody': 0.78; 'actually,': 0.84; 'arrangement.': 0.84; 'benefits:': 0.84; 'complexity': 0.84; 'distinguish': 0.84; 'do:': 0.84; 'enhances': 0.84; 'everything.': 0.84; 'nice,': 0.84; 'situations,': 0.84; '3.3': 0.91; 'dirty': 0.91; 'everything,': 0.91; 'received:98.138.90.53': 0.91; 'trouble.': 0.91; 'magical': 0.93 X-Yahoo-Newman-Property: ymail-3 X-Yahoo-Newman-Id: 270375.10474.bm@omp1003.mail.ne1.yahoo.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s1024; t=1333418242; bh=kt2ddT06iC2hBKKd8H5/gOc+a2oCiidmvPWU3VRijD0=; h=X-YMail-OSG:Received:X-Mailer:References:Message-ID:Date:From:Reply-To:Subject:To:In-Reply-To:MIME-Version:Content-Type:Content-Transfer-Encoding; b=ieR0k3RTf82FsA0GhB2nieppGhptt4SlJbbokz31K13w3lm23PmBnRKJdxixyFFBQtODZK6DHiI1vwIBiMtGINJwqjFbT3NnNEBjBDjPLfwkeScNKKD22RVfwJVKW/VGdrQ5ofB8urW9eQbFryWtTOwdJ/5DOM36nealPZy6H8s= DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=s1024; d=yahoo.com; h=X-YMail-OSG:Received:X-Mailer:References:Message-ID:Date:From:Reply-To:Subject:To:In-Reply-To:MIME-Version:Content-Type:Content-Transfer-Encoding; b=BcYa32P34I1ruLGyKkOSI2gf2/wjTOSnh/aEdxveuSp8eGzKWWyR/y4ODqfEjr/gl4yPqC4+Ne96YtoHQc65JEJT/7FRdlwh78ZgjJrFHbMBkM3de9MPwO9hoGIN74g+3KMwS7SF4PiSc4n0lPLeD6PaLTNqm3IqVDEg/Y8Oc7U=; X-YMail-OSG: NZga.4EVM1ngC01OBHNf2rWNuHPvs99WePU0RNwvp3qal9L 6E69MwDRNhzYfCTCgq.UKRxV_lq67MOus4qJgLl13EnJiwnNMJsrobnw2fL5 wIl0b5twNRRFFcfY3QBbNqX4UE3HbJvA9nZ.zQgtL2FKUO214cAz4XxXRaI7 lPtpIgeSSyz1gIcZ_TN0rAHdVQmEcYkwHQu1tqmltMwCYnjv3ZqrL38OQ_5A W9w6tNcTmzyF1BlcZT7E9IKAKgPey05ISwmZR0JWoeiffuDzU.zuYmaWlUFZ AcnWs.UO0ViJDoICt7wR9L5UlUYbRfI9ez._.ZXDk3NyhesaFjAGiwr7NGeM 58ZaTI5YRKg.UxhNARUSVIRq9DBKB03JDbGpZyB_CnSdWNjtcO4oYnlvsUKT wb4lXCI__3p6O6c0j6hQuJG54u0wHPCFku_mU4V098ioy_bp9RcVOmb1VHwH essxmCgn.GcdbYUuVRtokGwQ- X-Mailer: YahooMailWebService/0.8.117.340979 References: <1333174946.18436.YahooMailNeo@web121506.mail.ne1.yahoo.com> <4f7962b0$0$29981$c3e8da3$5496439d@news.astraweb.com> <1333357906.6147.YahooMailNeo@web121503.mail.ne1.yahoo.com> <1333367201.47465.YahooMailNeo@web121506.mail.ne1.yahoo.com> <1333381766.14038.YahooMailNeo@web121504.mail.ne1.yahoo.com> Date: Mon, 2 Apr 2012 18:57:22 -0700 (PDT) From: Yingjie Lan Subject: Re: string interpolation for python To: "python-list@python.org" In-Reply-To: MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Transfer-Encoding: quoted-printable X-BeenThere: python-list@python.org X-Mailman-Version: 2.1.12 Precedence: list Reply-To: Yingjie Lan 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: 70 NNTP-Posting-Host: 2001:888:2000:d::a6 X-Trace: 1333418251 news.xs4all.nl 6978 [2001:888:2000:d::a6]:59021 X-Complaints-To: abuse@xs4all.nl Xref: csiph.com comp.lang.python:22565 >>> I can't find a way to use an argument more than once,=0A=0A>>> withou= t switching to "dictionary mode" and using keys for =0A>>> everything.=0A= =0A=0AEven in "dictionary mode", the key is spelled more than=0A=0Aonce. Th= e "tuple mode" below seems to save some typing.=A0=0A=0AHowever, when there= are more and more items to format,=A0=0Athe readability=A0deteriorates qui= ckly in the "tuple" mode.=0A=0AUse an argument more than once is, after all= , probably a=0Anot-so-often use case.=0A=0A=0AThe "dictionary mode" greatly= enhances readability, but=A0=0Ayou have=A0to provide a dict object and mak= e sure the name in=A0=0Ayour=A0formatting string matches=A0the keys in the = dictionary.=0AAnd this matching requirement is because of information=0Ared= undancy in the arrangement. And information redundancy=0Ais often the root = of evil for various kinds of trouble.=0A=0ADynamic string seems to have the= good without redundancy.=0AAnd there is no need to build a dict for it.=A0= =0AHowever, when there is already the dict for use,=A0=0Aclearly the dict f= ormat is the winner.=0A>> Ack.=0A>> =0A>> In this case, you can use forma= t:=0A>> =0A>>>>> "Hello {0}, what's up with {1}? Hey, {0} I'm =0A> speakin= g to you!".format=0A>> ('George', 'Melissa')=0A>> "Hello George, what's u= p with Melissa? Hey, George I'm =0A> speaking to you!"=0A> =0A> Or don't bo= ther with the initial string, and simply pass everything as=0A> arguments:= =0A> =0A> def yingjie_format(*args):=0A> =A0 =A0 it=3Diter(args)=0A> =A0 = =A0 return ''.join(s%next(it,None) for s in it)=0A> yingjie_format("sin(%s"= ,x,") =3D %0.3f", sin(x))=0A>=A0=0A=0AThat's very nice, thanks!=0A=0A> So i= f they're exactly like normal expressions, why not simply use=0A=0A> normal= expressions?=0A=0A=0AI think use dynamic strings can have these benefits:= =0A1) you less keys (punch less keys).=0A2) better readability (less clutte= rs)=0A3) you don't have to explicit convert/format expressions into strings= =0A4) better performance too (adding strings together is generally slow).= =0A=A0=0A=0A>>> sprintf("UPDATE tablename SET modified=3Dnow()%{,%s=3D:%[0= ]s%} WHERE=0A>>> key=3D%d",array_of_field_names,primary_key_value)=0A>>> = --> "UPDATE tablename SET =0A> modified=3Dnow(),foo=3D:foo,bar=3D:bar,quux= =3D:quux=0A>>> WHERE key=3D1234"=0A>>> =0A>>> You're still paying for no = complexity you aren't actually =0A> using.=0A>>> It's=A0clear and readable= .=0A>> =0A>> You are really good at that. Maybe not everybody is as=0A>> = experience as you, and I suppose the learning curve is=0A>> kind of hard t= o climb.=0A> =0A> Yes, it takes some learning to use it. But that's true of= everything,=0A> no less of your magical string interpolation. My point is = that simple=0A> examples should be (and are, with printf formatting) simple= , such that=0A> you only get those more complicated format strings when you= 're=0A> actually doing a complicated job (in that case, taking each element= of=0A> an array and using it twice - actually, it was taking the indices o= f a=0A> mapping that would end up being passed to the DB query function, th= us=0A> providing values to the :foo :bar variables).=0A>=A0=0A=0ASure. But = if one thing does well on both simple and complex=A0=0Asituations, why not = that thing?=0A=0A>> Those expressions are embedded, you don't need eval()= =0A>> to have the result though. Are we on the same page?=0A> =0A> I can s= ee three implementation paths:=0A> =0A> 1) Language feature. It really *is*= just an expression. There's no way=0A> that a user can provide them, so th= ere's actually no similarity to=0A> eval. But this requires that Python its= elf handle things.=0A> =0A> 2) Precompiler. It *becomes* an expression. Aga= in, perfectly safe,=0A> although I don't know how useful this really is.=0A= > =0A> 3) Functoin. As several have suggested, you could do some magic and= =0A> use d("this is a $dollar$ $interpolated$ string") to implement. For=0A= > this, you *will* need eval (or something like it).=0A>=A0=0A=0ASure. for = 1), things can be done most conveniently and efficiently.=0Afor 2), yeah, n= ot sure how useful it is.=0Afor 3), maybe can let str class have a property= like: dy.=0Awhich can do all the dirty processing. Then we may do:=0A>>> x= =3D 0=0A>>> "sin($x$) =3D $sin(x)$".dy=0A'sin(0) =3D 0.0'=0A=0ANot much bu= rden to use except for the CPU, I suppose.=0A=0A>> You mean a translator?= =0A> =0A> Yes. It translates your dollar-strings into something that's lega= l=0A> Python 3.3 syntax - either calls to a function like I provided above,= =0A> or actual embedded expressions.=0A> =0A>> The syntax is essential for= compatibility.=0A>> We must distinguish dynamic strings from common strin= gs.=0A>> They will live peacefully together.=0A>> (escaping the '$' in no= rmal strings breaks compatibility,=0A>> and the consequence of forgetting = to escape could be=0A>> disastrous, so definitely not an option).=0A>> =0A= >> May be d" is too tiny, $"..." is easier to pick out.=0A> =0A> I don't l= ike the use of symbols like that; can someone, glancing at=0A> your code, t= ell whether $ is an operator, a name, or something else?=0A> The original d= is probably better for that.=0A>=A0=0A=0A=0AYeah, the d is probably better= .=A0=0A=0ACheers,=0AYingjie=0A