Python Cookbook 2Nd Edition Jun 1002005 [Electronic resources] نسخه متنی

اینجــــا یک کتابخانه دیجیتالی است

با بیش از 100000 منبع الکترونیکی رایگان به زبان فارسی ، عربی و انگلیسی

Python Cookbook 2Nd Edition Jun 1002005 [Electronic resources] - نسخه متنی

David Ascher, Alex Martelli, Anna Ravenscroft

| نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
لیست موضوعات
توضیحات
افزودن یادداشت جدید







Recipe 1.9. Simplifying Usage of Strings' translate Method


Credit: Chris Perkins, Raymond Hettinger


Problem


You often want to use the fast code in
strings' TRanslate method, but
find it hard to remember in detail how that method and the function
string.maketrans work, so you want a handy
facade to simplify their use in typical cases.


Solution


The TRanslate method of strings is quite powerful
and flexible, as detailed in Recipe 1.10. However, exactly because of
that power and flexibility, it may be a nice idea to front it with a
"facade" that simplifies its
typical use. A little factory function,
returning a closure, can do wonders for this kind of
task:

import string
def translator(frm='', to='', delete='', keep=None):
if len(to) == 1:
to = to * len(frm)
trans = string.maketrans(frm, to)
if keep is not None:
allchars = string.maketrans('', '')
delete = allchars.translate(allchars, keep.translate(allchars, delete))
def translate(s):
return s.translate(trans, delete)
return translate


Discussion


I often find myself wanting to use strings'
translate method for any one of a few purposes,
but each time I have to stop and think about the details (see Recipe 1.10 for more information
about those details). So, I wrote myself a class (later remade into
the factory closure presented in this recipe's
Solution) to encapsulate various possibilities behind a
simpler-to-use facade. Now, when I want a function that keeps only
characters from a given set, I can easily build and use that
function:

>>> digits_only = translator(keep=string.digits)
>>> digits_only('Chris Perkins : 224-7992')
'2247992'

It's similarly simple when I want to
remove a set of characters:

>>> no_digits = translator(delete=string.digits)
>>> no_digits('Chris Perkins : 224-7992')
'Chris Perkins : -'

and when I want to replace a set of characters with a single
character:

>>> digits_to_hash = translator(from=string.digits, to='#')
>>> digits_to_hash('Chris Perkins : 224-7992')
'Chris Perkins : ###-####'

While the latter may appear to be a bit of a special case, it is a
task that keeps coming up for me every once in a while.

I had to make one arbitrary design decision in this
recipenamely, I decided that the delete
parameter "trumps" the
keep parameter if they overlap:

>>> trans = translator(delete='abcd', keep='cdef')
>>> trans('abcdefg')
'ef'

For your applications it might be preferable to ignore
delete if keep is specified, or,
perhaps better, to raise an exception if they are both specified,
since it may not make much sense to let them both be given in the
same call to translator, anyway. Also: as noted in
Recipe 1.8 and Recipe 1.10, the code in this
recipe works only for normal strings, not for
Unicode strings. See Recipe 1.10 to learn how to code this
kind of functionality for Unicode strings, whose
translate method is different from that of plain
(i.e., byte) strings.


Closures


A
closure is nothing terribly complicated: just
an "inner" function that refers to
names (variables) that are local to an
"outer" function containing it.
Canonical toy-level example:

def make_adder(addend):
def adder(augend): return augend+addend
return adder

Executing p = make_adder(23) makes a closure of
inner function adder internally referring to a name
addend that is bound to the value 23. Then,
q = make_adder(42) makes
another closure, for which, internally, name
addend is instead bound to the value 42. Making
q in no way interferes with
p, they can happily and independently
coexist. So we can now execute, say, print p(100),
q(100)
and enjoy the output 123 142.

In practice, you may often see make_adder referred
to as a closure rather than by the pedantic,
ponderous periphrasis "a function that returns a
closure"fortunately, context often clarifies
the situation. Calling make_adder a
factory (or factory
function
) is both accurate and concise; you may also say
it's a closure factory to
specify it builds and returns closures, rather than, say, classes or
class instances.


See Also


Recipe 1.10 for a direct
equivalent of this recipe's
TRanslator(keep=...), more information on the
TRanslate method, and an equivalent approach for
Unicode strings; documentation for strings'
translate method, and for the
maketrans function in the
string module, in the Library
Reference
and Python in a
Nutshell
.


/ 394