Python JSON Serialize Dictionary - PullRequest
       3

Python JSON Serialize Dictionary

0 голосов
/ 01 ноября 2019

У меня есть словарь с ключевой строкой (2019-10-28 13:21) и значением объекта (DataPoint)

import requests
import json
import time

symbol = "AAPL"

intraday_url = "https://www.alphavantage.co/query?function=TIME_SERIES_INTRADAY&symbol="+symbol+"&interval=1min&outputsize=full&apikey="+api_key
sma_url = "https://www.alphavantage.co/query?function=SMA&symbol="+symbol+"&interval=1min&time_period=180&series_type=open&apikey="+api_key
ema_url = "https://www.alphavantage.co/query?function=EMA&symbol="+symbol+"&interval=1min&time_period=15&series_type=open&apikey="+api_key
vwap_url = "https://www.alphavantage.co/query?function=VWAP&symbol="+symbol+"&interval=1min&apikey="+api_key
macd_url = "https://www.alphavantage.co/query?function=MACD&symbol="+symbol+"&interval=1min&series_type=open&apikey="+api_key
rsi_url = "https://www.alphavantage.co/query?function=RSI&symbol="+symbol+"&interval=1min&time_period=100&series_type=open&apikey="+api_key
adx_url = "https://www.alphavantage.co/query?function=ADX&symbol="+symbol+"&interval=1min&time_period=100&apikey="+api_key

class DataPoint:
    def __init__(self, time):
        # 2019-10-31 15:49:00 (original)
        # 2019-10-31 15:49 (formatted)
        formatted_time = time[0:len(time)-3]
        self.time = formatted_time
        self.open = None
        self.high = None
        self.low = None
        self.close = None
        self.volume = None
        self.sma = None
        self.ema = None
        self.vwap = None
        self.macd = None
        self.rsi = None
        self.adx = None

    def addIntraday(self,open,high,low,close,volume):
        self.open = open
        self.high = high
        self.low = low
        self.close = close
        self.volume = volume

    def addTechnical(self,technical,value):
        if technical == "SMA":
            self.sma = value
        elif technical == "EMA":
            self.ema = value
        elif technical == "VWAP":
            self.vwap = value
        elif technical == "MACD":
            self.macd = value
        elif technical == "RSI":
            self.rsi = value
        elif technical == "ADX":
            self.adx = value

def getIntraday(dictionary):
    url = intraday_url
    response = requests.get(url)
    json = response.json()
    intraday = json.get("Time Series (1min)")
    keys = intraday.keys()
    for key in keys:
        ts = intraday.get(key)
        dp = DataPoint(key)
        open = ts.get("1. open")
        high = ts.get("2. high")
        low = ts.get("3. low")
        close = ts.get("4. close")
        volume = ts.get("5. volume")
        dp.addIntraday(open,high,low,close,volume)
        dictionary[dp.time] = dp

def getTechnicals(dictionary):
    urls = [sma_url, ema_url, vwap_url, macd_url, rsi_url, adx_url]
    technicals = ["SMA","EMA","VWAP","MACD","RSI","ADX"]
    i = 0
    while (i < len(urls)):
        response = requests.get(urls[i])
        json = response.json()
        tech = json.get("Technical Analysis: " + technicals[i])
        if (tech == None):
            print("Empty response, retrying in 10 seconds...")
            time.sleep(10)
        else:
            print("Getting Technical Indicator: " + technicals[i])
            keys = tech.keys()
            for key in keys:
                t = tech.get(key)
                v = t.get(technicals[i])
                if (dictionary.get(key) != None):
                    dictionary.get(key).addTechnical(technicals[i], v)
            i += 1

def writeDictionaryToFile(dictionary):
    filename = "datapoints.json"
    fp = open(filename, "a")
    json_dictionary = json.dumps(dictionary)
    fp.write(json_dictionary)
    print("Wrote results to file: " + filename)

dictionary = {}

getIntraday(dictionary)

getTechnicals(dictionary)

writeDictionaryToFile(dictionary)

Вот ошибка:

Traceback (most recent call last):
  File "/Users/Jason/Dev/Python/neural-network-example/alphavantage.py", line 124, in <module>
    writeDictionaryToFile(dictionary)
  File "/Users/Jason/Dev/Python/neural-network-example/alphavantage.py", line 113, in writeDictionaryToFile
    json_dictionary = json.dumps(dictionary)
  File "/usr/local/Cellar/python/3.7.4_1/Frameworks/Python.framework/Versions/3.7/lib/python3.7/json/__init__.py", line 231, in dumps
    return _default_encoder.encode(obj)
  File "/usr/local/Cellar/python/3.7.4_1/Frameworks/Python.framework/Versions/3.7/lib/python3.7/json/encoder.py", line 199, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "/usr/local/Cellar/python/3.7.4_1/Frameworks/Python.framework/Versions/3.7/lib/python3.7/json/encoder.py", line 257, in iterencode
    return _iterencode(o, 0)
  File "/usr/local/Cellar/python/3.7.4_1/Frameworks/Python.framework/Versions/3.7/lib/python3.7/json/encoder.py", line 179, in default
    raise TypeError(f'Object of type {o.__class__.__name__} '
TypeError: Object of type DataPoint is not JSON serializable

Насколько я понимаю, я могу использовать json.dumps () для общего типа данных Python, строки, int, словаря массивов и т. Д. Но я не могу использовать его для созданных мной пользовательских объектов. Я провел исследование, и из своего исследования я решил использовать myCustomObject. dict , чтобы сделать объект сериализуемым. Как я могу использовать это, когда я пытаюсь сериализовать весь словарь?

Я новичок в Python, я просто не могу понять это. Любая помощь с благодарностью.

Ответы [ 2 ]

4 голосов
/ 01 ноября 2019

Этого можно добиться с помощью специального сериализатора JSON, но это может оказаться излишним для вашей задачи. Более простое решение - дать вашему классу пару методов для преобразования в JSON и обратно через словари.

В вашем классе довольно много полей, поэтому я приведу более простой пример для игрушечного класса,которые вы должны быть в состоянии адаптировать для вашей цели:

import json

class Example:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def to_json(self):
        return json.dumps({
            'x': self.x,
            'y': self.y
        })

    @classmethod
    def from_json(cls, s):
        d = json.loads(s)
        return cls(d['x'], d['y'])

Использование:

>>> ex = Example(1, 2)
>>> s = ex.to_json()
>>> s
'{"y": 2, "x": 1}'
>>> ex2 = Example.from_json(s)
>>> ex2.x
1
>>> ex2.y
2
1 голос
/ 01 ноября 2019

json - очень переносимый формат, но он также ограничен. С помощью Json можно сериализовать только следующие вещи:

dicts - {} (all keys must be strings)
lists - []
strings - "string"
integers - 0, 1, 2, ...
True
False
None

Таким образом, вам придется преобразовать ваш объект в некоторую комбинацию этих вещей и иметь код для его преобразования обратно.

Есливы планируете ТОЛЬКО использовать python, вас может заинтересовать pickle, который может сериализовать произвольные объекты python, если он может импортировать модули, в которых они были определены. Учтите, что распаковка консервантов из неизвестных источников может привести к удаленному выполнению кода

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...