Python 更好的写法

循环列表, 直到找到符合的结果, 没有结果返回一个默认值

通常这样:

a = -1
for i in range(1, 10):
    if not i % 4:
        a = i
        break
# a = 4

更好的写法:

a = next((i for i in range(1, 10) if not i % 4), -1)
# a = 4

next(iterator[, default])

Retrieve the next item from the iterator by calling its __next__() method. If default is given, it is returned if the iterator is exhausted, otherwise StopIteration is raised.

 

标记区分

通常这样:

def find(seq, target):
    found = False
    for i, value in enumerate(seq):
        if value == target:
            found = True
            break
    if not found:
        return -1
    return i

更好的写法:

Python 3.4.1 (v3.4.1:c0e311e010fc, May 18 2014, 10:45:13) [MSC v.1600 64 bit (AMD64)] on win32
Type "copyright", "credits" or "license()" for more information.
>>> def find(seq, target):
    for i, value in enumerate(seq):
        if value == target:
            break
    else:
        return -1
    return i

>>> find(list(), 'a')
-1
>>> 

enumerate(iterable, start=0)

Return an enumerate object. iterable must be a sequence, an iterator, or some other object which supports iteration. The __next__() method of the iterator returned by enumerate() returns a tuple containing a count (from start which defaults to 0) and the values obtained from iterating over iterable.

 

threading.Lock

通常是这样的:

lock = threading.Lock()
lock.acquire()

try:
    print 'Critical section 1'
    print 'Critical section 2'
finally:
    lock.release()

更好的写法:

lock = threading.Lock()

with lock:
    print 'Critical section 1'
    print 'Critical section 2'
Python 3.4.1 (v3.4.1:c0e311e010fc, May 18 2014, 10:45:13) [MSC v.1600 64 bit (AMD64)] on win32
Type "copyright", "credits" or "license()" for more information.
>>> lock = threading.Lock()
>>> with lock:
    print("critical section 1")
    print("critical section 2")

    
critical section 1
critical section 2
>>> lock.locked()
False
>>> 

 

忽略抛出的异常

通常这样:

try:
    os.remove('somefile.tmp')
except OSError:
    pass

更好的写法:

Python 3.4.1 (v3.4.1:c0e311e010fc, May 18 2014, 10:45:13) [MSC v.1600 64 bit (AMD64)] on win32
Type "copyright", "credits" or "license()" for more information.
>>> import os
>>> from contextlib  import suppress
>>> with suppress(OSError, NameError):
    os.remove('dont.dat')

>>> 
>>> 

contextlib.suppress 类的实现如下:

class suppress:
    def __init__(self, *exceptions):
        self._exceptions = exceptions
    def __enter__(self):
        pass
    def __exit__(self, exctype, excinst, exctb):
        return exctype is not None and issubclass(exctype, self._exceptions)

 

Python 2.X 可以使用decorator @contextmanager 自定义一个ignore方法

@contextmanager
def ignored(*exceptions):
    try:
        yield
    except exceptions:
        pass

contextlib.suppress(*exceptions)

Return a context manager that suppresses any of the specified exceptions if they occur in the body of a with statement and then resumes execution with the first statement following the end of the with statement.

As with any other mechanism that completely suppresses exceptions, this context manager should be used only to cover very specific errors where silently continuing with program execution is known to be the right thing to do.

 

直接把输出存进文件中

通常这样:

with open('help.txt', 'w') as f:
    oldstdout = sys.stdout
    sys.stdout = f
    try:
        help(pow)
    finally:
        sys.stdout = oldstdout

更好的写法:

Python 3.4.1 (v3.4.1:c0e311e010fc, May 18 2014, 10:45:13) [MSC v.1600 64 bit (AMD64)] on win32
Type "copyright", "credits" or "license()" for more information.
>>> from contextlib import redirect_stdout
>>> with open(r'd:\help_pow.txt', 'w') as f:
    with redirect_stdout(f):
        help(pow)
        
>>> 

contextlib.redirect_stdout类的实现如下:

class redirect_stdout:
    """Context manager for temporarily redirecting stdout to another file

        # How to send help() to stderr
        with redirect_stdout(sys.stderr):
            help(dir)

        # How to write help() to a file
        with open('help.txt', 'w') as f:
            with redirect_stdout(f):
                help(pow)
    """

    def __init__(self, new_target):
        self._new_target = new_target
        # We use a list of old targets to make this CM re-entrant
        self._old_targets = []

    def __enter__(self):
        self._old_targets.append(sys.stdout)
        sys.stdout = self._new_target
        return self._new_target

    def __exit__(self, exctype, excinst, exctb):
        sys.stdout = self._old_targets.pop()

contextlib.redirect_stdout(new_target)

Context manager for temporarily redirecting sys.stdout to another file or file-like object.

This tool adds flexibility to existing functions or classes whose output is hardwired to stdout.

For example, the output of help() normally is sent to sys.stdout. You can capture that output in a string by redirecting the output to a io.StringIO object:

 

最简单的缓存

通常这样实现缓存:

def web_lookup(url, saved={}):
    if url in saved:
        return saved[url]
    page = urllib.urlopen(url).read()
    saved[url] = page
    return page

更好的写法:

@cache
def web_lookup(url):
    return urllib.urlopen(url).read()

def cache(func):
    saved = {}
    @wraps(func)
    def newfunc(*args):
        if args in saved:
            return newfunc(*args)
        result = func(*args)
        saved[args] = result
        return result
    return newfunc

# 没有验证

 

posted @ 2015-10-27 10:36  LABCD  阅读(299)  评论(0)    收藏  举报