Anda dapat membuat kode bytecode fungsi dan kemudian menyusunnya kembali pada pemanggil. The marshal modul dapat digunakan untuk benda kode deserialisasi, yang kemudian dapat kembali ke dalam fungsi. yaitu:
import marshal
def foo(x): return x*x
code_string = marshal.dumps(foo.func_code)
Kemudian dalam proses jarak jauh (setelah mentransfer code_string):
import marshal, types
code = marshal.loads(code_string)
func = types.FunctionType(code, globals(), "some_func_name")
func(10) # gives 100
Beberapa peringatan:
format marshal (semua bytecode python dalam hal ini) mungkin tidak cocok antara versi python utama.
Hanya akan berfungsi untuk implementasi cpython.
Jika fungsi mereferensikan global (termasuk modul yang diimpor, fungsi lain, dll) yang perlu Anda ambil, Anda perlu membuat serial ini juga, atau membuatnya kembali di sisi jarak jauh. Contoh saya hanya memberikan namespace global proses jarak jauh.
Anda mungkin perlu melakukan sedikit lebih banyak untuk mendukung kasus yang lebih kompleks, seperti penutupan atau fungsi generator.
marshal
modul untuk membuat serial kamus kamus yang diinisialisasi sebagaidefaultdict(lambda : defaultdict(int))
. Tapi itu mengembalikan kesalahanValueError: unmarshallable object
. Perhatikan bahwa saya menggunakan python2.7. Ada ide? Terima kasihfoo.func_code
kenaikanAttributeError
. Apakah ada cara lain untuk mendapatkan kode fungsi?Lihat Dill , yang memperluas pustaka acar Python untuk mendukung lebih banyak jenis, termasuk fungsi:
Ini juga mendukung referensi ke objek dalam penutupan fungsi:
sumber
Pyro dapat melakukan ini untuk Anda .
sumber
Cara yang paling sederhana mungkin
inspect.getsource(object)
(lihat modul inspeksi ) yang mengembalikan String dengan kode sumber untuk suatu fungsi atau metode.sumber
Itu semua tergantung pada apakah Anda membuat fungsi saat runtime atau tidak:
Jika Anda melakukannya -
inspect.getsource(object)
tidak akan berfungsi untuk fungsi yang dibuat secara dinamis karena ia mendapatkan sumber objek dari.py
file, jadi hanya fungsi yang ditentukan sebelum eksekusi yang dapat diambil sebagai sumber.Dan jika fungsi Anda ditempatkan dalam file, mengapa tidak memberikan akses kepada penerima dan hanya menyebarkan nama modul dan fungsi.
Satu-satunya solusi untuk fungsi yang dibuat secara dinamis yang dapat saya pikirkan adalah membangun fungsi sebagai string sebelum transmisi, mengirimkan sumber, dan kemudian
eval()
di sisi penerima.Sunting:
marshal
solusinya terlihat juga cukup pintar, tidak tahu Anda dapat membuat serialisasi sesuatu yang lain yang ada di dalamnyasumber
The
cloud
paket (pip install awan) dapat acar kode sewenang-wenang, termasuk dependensi. Lihat https://stackoverflow.com/a/16891169/1264797 .sumber
Sekarang
sumber
Kamu bisa melakukan ini:
Sekarang,
transmit(fn_generator())
akan mengirimkan definisi sebenarnya darifn(x,y)
alih-alih referensi ke nama modul.Anda dapat menggunakan trik yang sama untuk mengirim kelas melalui jaringan.
sumber
Fungsi dasar yang digunakan untuk modul ini mencakup kueri Anda, ditambah lagi Anda mendapatkan kompresi terbaik; lihat kode sumber instruktif:
y_serial.py module :: gudang objek Python dengan SQLite
"Serialization + persistance :: dalam beberapa baris kode, kompres dan beri anotasi objek Python ke dalam SQLite; kemudian ambil secara kronologis dengan kata kunci tanpa SQL. Modul" standar "yang paling berguna untuk database untuk menyimpan data tanpa skema."
http://yserial.sourceforge.net
sumber
Cloudpickle mungkin adalah yang Anda cari. Cloudpickle dijelaskan sebagai berikut:
Contoh penggunaan:
sumber
Berikut adalah kelas helper yang dapat Anda gunakan untuk menggabungkan fungsi agar dapat dipilih. Peringatan yang telah disebutkan untuk
marshal
akan berlaku tetapi diusahakan untuk menggunakan acar bila memungkinkan. Tidak ada upaya yang dilakukan untuk melestarikan global atau penutupan di seluruh serialisasi.sumber