[python] 파이썬 함수를 피클 (또는 코드를 직렬화)하는 쉬운 방법이 있습니까?

네트워크 연결을 통해 기능을 전송하려고합니다 (asyncore 사용). 이와 같은 전송을 위해 Python 함수 (이 경우 적어도 부작용이없는 함수)를 직렬화하는 쉬운 방법이 있습니까?

이상적으로는 다음과 같은 한 쌍의 기능을 갖고 싶습니다.

def transmit(func):
    obj = pickle.dumps(func)
    [send obj across the network]

def receive():
    [receive obj from the network]
    func = pickle.loads(s)
    func()



답변

함수 바이트 코드를 직렬화 한 다음 호출자에서 재구성 할 수 있습니다. 정렬 화 모듈은 다음의 함수로 재 조립 될 수 직렬화를 코드 오브젝트로 사용할 수있다. 즉 :

import marshal
def foo(x): return x*x
code_string = marshal.dumps(foo.func_code)

그런 다음 원격 프로세스에서 (code_string 전송 후) :

import marshal, types

code = marshal.loads(code_string)
func = types.FunctionType(code, globals(), "some_func_name")

func(10)  # gives 100

몇 가지주의 사항 :

  • marshal의 형식 (해당 문제에 대한 모든 파이썬 바이트 코드)은 주요 파이썬 버전간에 호환되지 않을 수 있습니다.

  • cpython 구현에서만 작동합니다.

  • 함수가 선택해야하는 전역 (가져온 모듈, 기타 함수 등 포함)을 참조하는 경우 이들도 직렬화하거나 원격 측에서 다시 만들어야합니다. 내 예제는 원격 프로세스의 전역 네임 스페이스를 제공합니다.

  • 클로저 또는 생성기 함수와 같은 더 복잡한 경우를 지원하려면 더 많은 작업을 수행해야 할 것입니다.


답변

Python의 pickle 라이브러리를 확장하여 함수를 포함한 다양한 유형을 지원하는 Dill을 확인하십시오 .

>>> import dill as pickle
>>> def f(x): return x + 1
...
>>> g = pickle.dumps(f)
>>> f(1)
2
>>> pickle.loads(g)(1)
2

또한 함수의 클로저에서 객체에 대한 참조를 지원합니다.

>>> def plusTwo(x): return f(f(x))
...
>>> pickle.loads(pickle.dumps(plusTwo))(1)
3


답변


답변

가장 간단한 방법은 아마도 inspect.getsource(object)( inspect 모듈 참조 ) 함수 나 메서드의 소스 코드와 함께 문자열을 반환하는 것입니다.


답변

그것은 모두 런타임에 함수를 생성하는지 여부에 달려 있습니다.

그렇게하면- 파일 inspect.getsource(object)에서 객체의 소스를 가져 오므로 동적으로 생성 된 함수에 대해 작동하지 않으므로 .py실행 전에 정의 된 함수 만 소스로 검색 할 수 있습니다.

어쨌든 함수가 파일에 배치되어 있다면 수신기 액세스 권한을 부여하고 모듈 및 함수 이름 만 전달하십시오.

내가 생각할 수있는 동적으로 생성 된 함수에 대한 유일한 해결책은 전송 전에 문자열로 함수를 구성하고 소스를 전송 한 다음 eval()수신기 측에서 함수를 구성하는 것입니다 .

편집 : marshal솔루션도 꽤 똑똑해 보이며 내장 된 다른 것을 직렬화 할 수 있다는 것을 몰랐습니다.


답변

cloud패키지 (클라우드를 설치 PIP) 의존성을 포함하여 임의의 코드를, 피클 수 있습니다. https://stackoverflow.com/a/16891169/1264797을 참조 하십시오 .


답변

code_string = '' '
def foo (x) :
    반환 x * 2
데프 바 (x) :
    반환 x ** 2
'' '

obj = pickle.dumps (코드 _ 문자열)

지금

exec (pickle.loads (obj))

foo (1)
> 2
바 (3)
> 9