파이썬 함수(또는 코드를 직렬화)를 쉽게 피킹할 수 있는 방법이 있습니까?
네트워크 연결을 통해 함수를 전송하려고 합니다(아시코어 사용).이렇게 전송하기 위해 파이썬 함수(이 경우 적어도 부작용이 없는 함수)를 직렬화하는 쉬운 방법이 있습니까?
다음과 유사한 기능을 사용하는 것이 이상적입니다.
def transmit(func):
obj = pickle.dumps(func)
[send obj across the network]
def receive():
[receive obj from the network]
func = pickle.loads(s)
func()
함수 바이트 코드를 직렬화한 다음 호출자에서 재구성할 수 있습니다.마샬 모듈은 코드 객체를 직렬화하는 데 사용할 수 있으며, 코드 객체는 함수로 재조립될 수 있습니다.i:
import marshal
def foo(x): return x*x
code_string = marshal.dumps(foo.__code__)
그런 다음 원격 프로세스에서(code_string 전송 후):
import marshal, types
code = marshal.loads(code_string)
func = types.FunctionType(code, globals(), "some_func_name")
func(10) # gives 100
몇 가지 주의 사항:
마샬의 형식(해당 사항에 대한 파이썬 바이트 코드)은 주요 파이썬 버전 간에 호환되지 않을 수 있습니다.
cypthon 구현에서만 작동합니다.
함수가 선택해야 하는 글로벌(가져온 모듈, 기타 기능 등)을 참조하는 경우 이러한 글로벌도 직렬화하거나 원격에서 다시 생성해야 합니다.이 예제에서는 원격 프로세스의 글로벌 네임스페이스를 제공합니다.
폐쇄나 발전기 기능과 같은 더 복잡한 사례를 지원하려면 좀 더 많은 작업이 필요할 것입니다.
Python의 피클 라이브러리를 확장하여 다음 기능을 포함한 더 다양한 유형을 지원하는 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)
(검사 모듈 참조) 함수 또는 메서드에 대한 소스 코드가 포함된 String을 반환합니다.
이 모든 것은 런타임에 함수를 생성하는지 여부에 따라 달라집니다.
당신이 한다면,inspect.getsource(object)
동적으로 생성된 함수는 객체의 소스를 가져올 때 작동하지 않습니다..py
실행 전에 정의된 함수만 소스로 검색할 수 있습니다.
그리고 기능이 파일에 저장되어 있다면 수신자에게 해당 기능에 대한 액세스 권한을 부여하고 모듈 및 기능 이름만 전달하는 것이 어떻습니까?
동적으로 생성된 함수에 대한 유일한 해결책은 전송 전에 문자열로 함수를 구성하고 전송 소스를 만든 다음eval()
수신기 쪽에 있습니다.
집편:marshal
꽤 , 할 수 있는지 내장된 다른 것을 직렬화할 수 있는지 몰랐습니다.
현대의 파이썬에서는 함수와 다양한 변형을 피클링할 수 있습니다.이 점을 고려해 보십시오.
import pickle, time
def foobar(a,b):
print("%r %r"%(a,b))
당신은 그것을 피클로 만들 수 있습니다.
p = pickle.dumps(foobar)
q = pickle.loads(p)
q(2,3)
당신은 피클 클로저를 사용할 수 있습니다.
import functools
foobar_closed = functools.partial(foobar,'locked')
p = pickle.dumps(foobar_closed)
q = pickle.loads(p)
q(2)
폐쇄가 로컬 변수를 사용하더라도
def closer():
z = time.time()
return functools.partial(foobar,z)
p = pickle.dumps(closer())
q = pickle.loads(p)
q(2)
그러나 내부 기능을 사용하여 닫으면 실패합니다.
def builder():
z = 'internal'
def mypartial(b):
return foobar(z,b)
return mypartial
p = pickle.dumps(builder())
q = pickle.loads(p)
q(2)
실수로
피클.피클링 오류:피클할 수 없습니다. <function mypartial at 0x7f3b6c885a50>: __main_.mypartial로 검색되지 않습니다.
Python 2.7 및 3.6으로 테스트됨
그cloud
패키지(인스턴스 설치 클라우드)는 종속성을 포함하여 임의 코드를 피클링할 수 있습니다.https://stackoverflow.com/a/16891169/1264797 을 참조하십시오.
code_string = ''defo(x):반환 x * 2정의 막대(x):반환 x ** 2''' obj = pickle.dll(code_string)
지금이다
exec(pickle.bullet(obj)) foo(1)> 2막대(3)> 9
클라우드 피클은 아마도 당신이 찾고 있는 것일 것입니다.클라우드 피클은 다음과 같이 설명됩니다.
클라우드 피클은 네트워크를 통해 Python 코드가 전송되어 데이터에 가까운 원격 호스트에서 실행되는 클러스터 컴퓨팅에 특히 유용합니다.
사용 예:
def add_one(n):
return n + 1
pickled_function = cloudpickle.dumps(add_one)
pickle.loads(pickled_function)(42)
다음을 수행할 수 있습니다.
def fn_generator():
def fn(x, y):
return x + y
return fn
지금이다,transmit(fn_generator())
는 실제 합니다.fn(x,y)
모듈 이름에 대한 참조 대신 사용합니다.
동일한 방법을 사용하여 네트워크를 통해 클래스를 보낼 수 있습니다.
이 모듈에 사용되는 기본 기능은 쿼리를 포함하며, 와이어를 통해 최상의 압축을 얻을 수 있습니다. 지침 소스 코드:
y_serial.py 모듈 :: SQLite를 사용하는 웨어하우스 Python 개체
"Serialization + persistance :: 몇 줄의 코드로 Python 객체를 SQLite로 압축 및 주석 처리한 다음 나중에 SQL 없이 키워드별로 시간순으로 검색합니다.데이터베이스가 스키마가 없는 데이터를 저장하는 데 가장 유용한 "표준" 모듈입니다."
http://yserial.sourceforge.net
다음은 함수를 선택할 수 있도록 래핑하는 데 사용할 수 있는 도우미 클래스입니다.다에 대이 언된주사항에 대해 된 주의 marshal
적용되지만 가능할 때마다 피클을 사용하도록 노력합니다.연속화 전반에 걸쳐 전역 또는 폐쇄를 보존하려는 노력은 없습니다.
class PicklableFunction:
def __init__(self, fun):
self._fun = fun
def __call__(self, *args, **kwargs):
return self._fun(*args, **kwargs)
def __getstate__(self):
try:
return pickle.dumps(self._fun)
except Exception:
return marshal.dumps((self._fun.__code__, self._fun.__name__))
def __setstate__(self, state):
try:
self._fun = pickle.loads(state)
except Exception:
code, name = marshal.loads(state)
self._fun = types.FunctionType(code, {}, name)
언급URL : https://stackoverflow.com/questions/1253528/is-there-an-easy-way-to-pickle-a-python-function-or-otherwise-serialize-its-cod
'programing' 카테고리의 다른 글
스프링 데이터 받침대 및 Cors (0) | 2023.07.27 |
---|---|
div 요소에서 키 누름(또는 키다운) 이벤트를 캡처하려면 어떻게 해야 합니까? (0) | 2023.07.27 |
CSS로만 된 대문자? (0) | 2023.07.27 |
한 페이지에서만 AJAX POST에서 NTLM 챌린지 받기 (0) | 2023.07.27 |
jQuery를 사용하여 브라우저 주소 표시줄 URL 변경 (0) | 2023.07.27 |