Python-진급-functools 모듈 소개

7561 단어

functools.partial


functools.partial은 포장 기법을 통해'재정의'함수 서명을 일부 기본 매개 변수로 호출 가능한 대상을 포장할 수 있습니다. 반환 결과는 호출 가능한 대상입니다. 또한 원시 대상처럼 일부 함수 위치 함수나 키워드 매개 변수를 동결하고 편지 수를 간소화하며 더욱 적고 유연한 함수 매개 변수 호출 응용을 할 수 있습니다. 전형적으로 함수는 실행할 때 필요한 모든 매개 변수를 가지고 호출해야 합니다.그리고 때때로 매개 변수는 함수가 호출되기 전에 미리 알 수 있다.이런 상황에서 함수는 함수가 더 적은 매개 변수로 호출될 수 있도록 한 개 이상의 매개 변수를 미리 사용할 수 있다.
import functools

def add(a, b):
    return a + b

if __name__ == '__main__':
    print add(3, 4)
    plus9 = functools.partial(add, 9)
    print plus9(11)
    plus7 = functools.partial(add, 5)
    print plus7(4)
    
C:\Python27\python.exe D:/wangyueWorkspace/mytest/functiontools/test1.py
7
20
9

functool.update_wrapper


기본 partial 대상은name과doc가 없습니다
def wrap(func):
    def call_it(*args, **kwargs):
        """wrap func: call it"""
        print 'before call'
        return func(*args, **kwargs)
    return call_it

@wrap
def hello():
    """hello"""
    print 'hello world!'
    
if __name__ == '__main__':
    hello()
    print hello.__name__
    print hello.__doc__
    
C:\Python27\python.exe D:/wangyueWorkspace/mytest/functiontools/test2.py
before call
hello world!
call_it
wrap func: call it

업데이트 사용wrapper는 봉인된 함수의name,module,doc,dict를 봉인된 함수로 복사할 수 있습니다(모듈 단계 상수 WRAPPER ASSIGNMENTS,WRAPPER UPDATES)

from functools import update_wrapper

def wrap2(func):
    def call_it(*args, **kwargs):
        """wrap2 func: call it"""
        print 'before call2'
        return func(*args, **kwargs)
    return update_wrapper(call_it, func)

@wrap2
def hello2():
    """hello2 test
    aaaaaaaaaaaaa
    asdfasdfad
    """
    print 'hello world2!'


if __name__ == '__main__':
    hello2()
    print hello2.__name__
    print hello2.__doc__
    
C:\Python27\python.exe D:/wangyueWorkspace/mytest/functiontools/test2.py  
before call2
hello world2!
hello2
hello2 test
aaaaaaaaaaaaa
asdfasdfad

이 함수는 주로 장식기 함수에 사용되며, 장식기 반환 함수는 원시 함수 정의가 아니라 포장 함수의 함수 정의를 반사한다

functool.wraps


함수 장식기partial(update wrapper, wrapped=wrapped, assigned=assigned, updated=updated)의 약자를 호출합니다.
from functools import wraps, update_wrapper

def mywrap(func):
    @wraps(func)
    def call_it(*args, **kwargs):
        """wrap func: call_it2"""
        print 'before call'
        return func(*args, **kwargs)

    update_wrapper(call_it, func)
    return call_it


@mywrap
def hello():
    """test hello"""
    print 'hello'


if __name__ == '__main__':
    hello()
    print hello.__name__
    print hello.__doc__


실행 효과 알 수 있음,functool.wraps 장식기와 업데이트wrapper 함수는 사실 효과가 똑같습니다. 모두 봉인된 함수의name__、module、__doc__및dict__모두 봉인 함수로 복사합니다.

질문:


==그런데 이상하게 cinder 코드에 이 두 가지를 동시에 썼어요. 철이 없어요. 왜???==
def _retry_on_deadlock(f):
    """Decorator to retry a DB API call if Deadlock was received."""

    @functools.wraps(f)
    def wrapped(*args, **kwargs):
        while True:
            try:
                return f(*args, **kwargs)
            except db_exc.DBDeadlock:
                LOG.warning(_LW("Deadlock detected when running "
                                "'%(func_name)s': Retrying..."),
                            dict(func_name=f.__name__))
                # Retry!
                time.sleep(0.5)
                continue

    functools.update_wrapper(wrapped, f)
    return wrapped

여기에 __name__、__doc__ __dict__의 역할:
  • python에서 하나의 모듈이 전체적으로 실행될 때moduel.name__`의 값은 "main"입니다.하나의 모듈이 다른 모듈에 인용될 때 모듈e.name__module 자신의 이름
  • >>> print dir.__name__
    dir
    >>> print __name__
    __main__
    
  • 함수마다 하나의 대상이고 함수마다 하나의doc__의 속성, 함수 문장에서 만약 첫 번째 표현식이 하나의string이라면 이 함수의doc__바로 이string, 그렇지 않으면doc__논이야.사실 함수 주석이에요~~
  • >>> def hello():
    ...     """hello function lalalal"""
    ...     print 'hello world'
    ...
    >>>
    >>> print hello.__doc__
    hello function lalalal
    
  • __dict__는 사전이고 키는 속성 이름이며 값은 속성 값이다.파이톤의 실례는 자신만의 이 있다dict__,그것에 대응하는 클래스도 자신의 가 있다dict__
  • >>> print file.__dict__
    {'softspace': , 'encoding': , 'xreadlines': , 'readlines': , 'flush': , 'close': , 'seek': , '__init__': , 'newlines': , '__setattr__': , 'errors': , '__new__': , 'readinto': , '__enter__': , 'next': , 'write': , 'closed': , 'tell': , 'mode': , '__exit__': , 'isatty': , 'truncate': , 'read': , '__getattribute__': , '__iter__': , 'readline': , 'fileno': , 'writelines': , 'name': , '__doc__': "file(name[, mode[, buffering]]) -> file object

    Open a file. The mode can be 'r', 'w' or 'a' for reading (default),
    writing or appending. The file will be created if it doesn't exist
    when opened for writing or appending; it will be truncated when
    opened for writing. Add a 'b' to the mode for binary files.
    Add a '+' to the mode to allow simultaneous reading and writing.
    If the buffering argument is given, 0 means unbuffered, 1 means line
    buffered, and larger numbers specify the buffer size. The preferred way
    to open a file is with the builtin open() function.
    Add a 'U' to mode to open the file for input with universal newline
    support. Any line ending in the input file will be seen as a '\
    '
    in Python. Also, a file so opened gains the attribute 'newlines';
    the value for this attribute is one of None (no newline read yet),
    '\\r', '\
    ', '\\r\
    ' or a tuple containing all the newline types seen.

    'U' cannot be combined with 'w' or '+' mode.
    ", '__delattr__': , '__repr__': }

    참조:


    Python-진급-functools 모듈 소결

    좋은 웹페이지 즐겨찾기