2017-07-05 5 views
0

私はPythonからRにデータを送るためにJSONを使用しています(注:私はPythonよりもRに慣れています)。プリミティブの場合、jsonモジュールはうまく機能します。他の多くのPythonオブジェクト(numpy配列など)では、stack overflow answerのようにカスタムエンコーダを定義する必要があります。しかし、それはjson.dumpsへの引数としてエンコーダを渡す必要がありますが、私の場合はうまくいきません。 json_tricksのような、JSONシリアライゼーションのはるかに高度な機能を備えているパッケージがあることは知っていますが、Pythonディストリビューションを管理することはできないため、オブジェクトをシリアル化するためにデフォルト以外のモジュールを使用したくないJSONへJSONシリアライズへのデコレータアプローチ

のデコレータを使用してJSONオブジェクトをシリアライズする追加の方法を定義する方法があるのだろうかと思います。理想的には、ユーザーがstandard_wrapperを変更することなく、独自のクラス(またはロードするモジュールのタイプ)の新しいメソッドを追加するために用意した標準関数standard_wrapperをオーバーライドできる方法を探しています。以下のいくつかの擬似コード:

import json 

def standard_wrapper(o): 
    return o 


obj = [44,64,13,4,79,2,454,89,0] 

json.dumps(obj) 
json.dumps(standard_wrapper(obj)) 

import numpy as np 
objnp = np.sort(obj) 

json.dumps(objnp) # FAILS 

@some_decorator_to_overload_standard_wrapper 
# some code 

json.dumps(standard_wrapper(objnp)) # HOPEFULLY WORKS 

これは、本質的にタイプによって過負荷に機能ですが---私はPythonでoverloading by argumentsの例を見てきましたが、私はタイプによってどのようにそれを行うには表示されません。

EDIT私はcontextlib(デコレータを使用したことがあります)のデコレータを混ぜていました。

+0

「contextlib」を使ってこのことを思い出しているのは私の謎です。何を思い浮かべましたか?それにもかかわらず、[** _オブジェクトJSONを通常のエンコーダでシリアライズすること**](https://stackoverflow.com/questions/18478287/making-object-json-serializable-with-regular-encoder)の回答は役に立ちます。 – martineau

+0

私はカスタムクラスのエンコーダを作成したくないので、既存のメソッドと競合しないカスタムの 'cls'オブジェクトを直列化するための独自のメソッドをユーザが定義できるようにするフレームワークが必要です。 'json.dumps'の引数です。私はRのS3メソッドに相当するPythonを探していると思います。 – mikeck

+0

リンクされた質問に対する私の答えを読んでいるように私には聞こえません。これは、jsonエンコーディングスキームにフックして、必要な処理を実行する方法を示しています。このコードでは、何もせずに多くの一般的なPython型をシリアライズすることができるので、 'pickle'を例として使用しています。これは拡張可能なシステムなので、多くの著者がクラスに対応するためのメソッドを追加しています。ユーザーが提供する "メソッド"を使って独自の "フレームワーク"を作るのはかなり簡単だと思いますが、そうすることで、適切なオブジェクトに関連付ける方法が必要になります。これを行う – martineau

答えて

0

singledispatchからfunctoolsモジュールまでは、answerのように種類によって関数をオーバーロードするのが簡単です。しかし、私のニーズに合った簡単な解決策は、キーがオブジェクトタイプに対応する関数の辞書を作成することです。

import numpy 
func_dict = {} 
a = [2,5,2,9,75,8,36,2,8] 
an = numpy.sort(a) 

func_dict[type(an)] = lambda x: x.tolist() 
func_dict[type(a)] = lambda x: x 

import json 
json.dumps(func_dict[type(a)](a)) 
json.dumps(func_dict[type(an)](an)) 

別の種類のサポートを追加するには、別の機能を辞書に追加します。

+0

これは簡単ですか?ユーザーのソリューションは、作成したタイプが何であるかを知る必要はありませんが、シリアル化するには、変換する適切なタイプを知る必要があります。適切なシリアライズ可能な型を知ることは、作成したデータ構造の型よりも発見するのが難しいようです。より簡単な答えは、この記事で説明する最初のオプションです。https://hynek.me/articles/serialization/ この記事のsingledispatchメソッドは、デコレータを使用して元の質問に答えています。ダイナミックディスパッチ。 – Davos

関連する問題