복붙노트

[PYTHON] 파이썬 함수의 복사본을 만드는 법 [duplicate]

PYTHON

파이썬 함수의 복사본을 만드는 법 [duplicate]

파이썬 함수의 실제 복사본을 만들 가능성이 있습니까? 가장 확실한 선택은 http://docs.python.org/2/library/copy.html 이었지만 읽었습니다.

함수의 일부 속성을 변경할 수 있기 때문에 실제 사본이 필요합니다.

최신 정보:

나는 코멘트에 언급 된 모든 가능성을 알고있다. 내 유스 케이스는 메타 프로그래밍을 기반으로하며, 여기에서 몇 가지 선언적 사양으로 클래스를 구성합니다. 완전한 세부 정보는 너무 길기 때문에, 기본적으로 다음과 같은 기능이 있습니다.

def do_something_usefull(self,arg):
    self.do_work()

이 메소드를 다양한 클래스에 추가 할 것이다. 클래스는 완전히 무관 할 수 있습니다. mixin 클래스를 사용하는 것은 옵션이 아닙니다 : 저는 그러한 많은 함수를 가지게 될 것이며, 결국 각 함수에 대한 기본 클래스를 추가하게 될 것입니다. 내 현재 "해결 방법"이 같은 "공장"이이 함수를 래핑하는 것입니다 :

def create_do_something():
    def do_something_usefull(self,arg):
        self.do_work()

그런 식으로 항상 새로운 do_something_useful 함수를 얻습니다.하지만이 모든 함수를 랩핑해야합니다.

내가 정상적인 OO 프로그래밍이 아니라는 것을 당신이 알고 있다고 믿을 수 있습니다. 나는 "정상적으로"그런 것을 풀 수있는 방법을 안다. 하지만 이것은 동적 코드 생성기이므로 모든 것을 가볍고 단순하게 유지하고 싶습니다. 그리고 파이썬 함수는 매우 일반적인 객체이기 때문에 복사하는 방법을 묻는 것이 너무 이상하다고 생각하지 않습니다.

해결법

  1. ==============================

    1.파이썬 2에서 :

    파이썬 2에서 :

    import types
    import functools
    def copy_func(f):
        """Based on http://stackoverflow.com/a/6528148/190597 (Glenn Maynard)"""
        g = types.FunctionType(f.func_code, f.func_globals, name=f.func_name,
                               argdefs=f.func_defaults,
                               closure=f.func_closure)
        g = functools.update_wrapper(g, f)
        return g
    
    def f(x, y=2):
        return x,y
    f.cache = [1,2,3]
    g = copy_func(f)
    
    print(f(1))
    print(g(1))
    print(g.cache)
    assert f is not g
    

    산출량

    (1, 2)
    (1, 2)
    [1, 2, 3]
    

    파이썬 3 :

    import types
    import functools
    
    def copy_func(f):
        """Based on http://stackoverflow.com/a/6528148/190597 (Glenn Maynard)"""
        g = types.FunctionType(f.__code__, f.__globals__, name=f.__name__,
                               argdefs=f.__defaults__,
                               closure=f.__closure__)
        g = functools.update_wrapper(g, f)
        g.__kwdefaults__ = f.__kwdefaults__
        return g
    
    def f(arg1, arg2, arg3, kwarg1="FOO", *args, kwarg2="BAR", kwarg3="BAZ"):
        return (arg1, arg2, arg3, args, kwarg1, kwarg2, kwarg3)
    f.cache = [1,2,3]
    g = copy_func(f)
    
    print(f(1,2,3,4,5))
    print(g(1,2,3,4,5))
    print(g.cache)
    assert f is not g
    

    산출량

    (1, 2, 3, (5,), 4, 'BAR', 'BAZ')
    (1, 2, 3, (5,), 4, 'BAR', 'BAZ')
    [1, 2, 3]
    
  2. from https://stackoverflow.com/questions/13503079/how-to-create-a-copy-of-a-python-function by cc-by-sa and MIT license