On Apr 18, 8:58 am, Aaron Watters <[EMAIL PROTECTED]> wrote: > Why is the migration to py3k a concern? > For example I have libraries which use string%dictionary > substitution where the dictionary is actually an object > which emulates a dictionary. The __getitem__ for > the object can be very expensive and is only called when > needed by the string substitution. > > In py3k string%dictionary is going away. Why? > I have no idea. > > The replacement is a string.format(...) method > which supports dictionary calling. > string.format(**dictionary) > But dictionary > calling doesn't support dictionary emulation. > So in the example below the substitution works > but the call fails. > > === code > > class fdict(dict): > def __getitem__(self, item): > return "got("+item+")" > > def fn(**d): > print d["boogie"] > > if __name__=="__main__": > fd = fdict() > print "attempting string substitution with fake dictionary" > print > print "hello there %(boogie)s" % fd # <-- works > print > print "now attempting function call with fake dictionary" > print > fn(**fd) # <-- fails > > === output > > % python2.6 dtest.py > attempting string substitution with fake dictionary > > hello there got(boogie) > > now attempting function call with fake dictionary > > Traceback (most recent call last): > File "dtest.py", line 17, in <module> > fn(**fd) > File "dtest.py", line 7, in fn > print d["boogie"] > KeyError: 'boogie' > > ==== end of output > > Consequently there is no simple way to translate > my code, I think. I suspect you will find this kind of subtle > issue in many places. Or worse, you won't find it > until after your program has been installed > in production. > > It's a damn shame because > if string%dict was just left in it wouldn't be an issue. > > Also, if making f(**d) support dict emulation > has any negative performance implications > then I don't want it please. > > sigh. -- Aaron Watters > > ===http://www.xfeedme.com/nucular/pydistro.py/go?FREETEXT=crack+open
The reason it doesn't work is that you are unpacking the dictionary with **, and you have done nothing to define any keys or define a length. I would describe the way you are using dict as a hack, and not part of any standard feature. You make a good point that it breaks your code, but at the same time the format facility gives you the ability to do something similar but in a standard way. You simply define a class with a __format__ method and pass that in instead of your dict. class MyClass: def __format__(self, spec): return "got({0})".format(spec) c = MyClass() print ("hey everybody {0:some words}".format(c)) print ("lets try this {0:more words} {0:even more words}".format(c)) should produce: hey everybody got(some words) lets try this got(more words) got(even more words) My point is that instead of exploiting the string formatting of dictionaries feature to create a custom format specifier, you actually get to define your own format specifiers, something which is much more powerful. And actually, you can do this too... which is even simpler and allows you to use your a portion of your existing solution: class fdict(dict): def __getitem__(self, item): return "got("+item+")" fd = fdict() print ("hello there {0[boogie]} hello there {0[george])".format(fd)) Which should result in: hello there got(boogie) hello there got(george) * Keep in mind that I have not tested any of this code, there may be bugs. I don't have Py3k or 2.6 installed locally. I think this is a good trade-off. Adding to that... don't worry about py3k. Nobody is forcing you to switch. In fact, you are encouraged not to until you are comfortable. Py3k won't _break_ your code. You wrote the code for Python 2.x use it in 2.x. Python 2.x probably has a good 5-10 years remaining. Matt -- http://mail.python.org/mailman/listinfo/python-list