在Python

时间:2018-02-01 22:03:06

标签: python api oop data-structures

我很难确定用于构建数据的最佳实践,以调用包含比特币价格的各种API。我希望能够调用多个API,而无需重复代码。

我最初的想法是为我要调用的每个API构建类,并将它们的属性(api_id,url和json_tree(json路径我想从中提取数据)提供给BtcAPI类,吐出来。

*注意,在阅读BtcAPI工作之前,Coindesk / Bitstamp类 尚未与该类进行交互。在我遇到麻烦之前,我想问一下我应该怎么做... *

现在,我想知道我是否不应该制作这些列表,例如:

coindesk = ['http://www.something.com', 'coindesk', '["time"]["updated"]']

...并且只是迭代它们中的每一个。或者说,或者其他各种各样的东西。这里指出了什么数据结构?

我基本上是在寻找一些代码审查(因为此代码不起作用,我不想将其发送到代码审查堆栈)并了解最佳做法:告诉我您认为我在哪里搞砸了,以及我可以做些什么来更好地构建这些数据?我是一个蟒蛇和oop noob。我可以在程序上做到这一点,但这将是丑陋和多余的。我想我也使用了一些错误的类。见解?救命?谢谢!

谢谢!

import json
import urllib.request

#The BtcAPI class works well when you feed it static variables. It returns json.

class BtcAPI:

    def __init__(self, url, api_id):
        self.url = url
        self.api_id = api_id

    def btc_api_call(self):

        hdr = { 'User-Agent' : 'Mozilla/5.0 (Windows NT 6.1; Win64; x64)'     }
        req = urllib.request.Request(url, headers=hdr)
        readdata = urllib.request.urlopen(req)
        json_data = readdata.read()

        json_dict = json.loads(json_data)
        return(json_dict)

class Coindesk:


    api_id = 'Coindesk'
    url = 'https://api.coindesk.com/v1/bpi/currentprice.json'               
    json_tree = json_dict['time']['updated']

    def __init__(self):

        self.current_us_price = current_us_price

class Bitstamp:


    api_id = 'Bitstamp'
    url = 'https://www.bitstamp.net/api/ticker/'               
    json_tree = json_dict['last']

    def __init__(self):

        self.current_us_price = current_us_price

coindesk_url = Coindesk()
coindeskoutput = coindesk_url.url
print(coindeskoutput)

2 个答案:

答案 0 :(得分:3)

如果你想要一个通用的代码片段,我建议你将代码和配置数据分离成2个文件。这样,您可以管理配置数据(要检索的URL,JSON属性),而无需修改实际的Python代码。这通常被认为是一种很好的做法,但它意味着要管理两个文件而不是一个文件,因此如果你是一个非常小的项目,这可能会有点负担。

在您的情况下,您可以:

  • conf.ini
  • bitcoin_api.py

<强> conf.ini

配置文件如下所示:

[COINDESK]
url: https://api.coindesk.com/v1/bpi/currentprice.json
response: time.updated

[BITSTAMP]
url: https://www.bitstamp.net/api/ticker
response: last

<强> bitcoin_api.py

您的代码如下所示:

import configparser
import requests
import os


class BitcoinAPI:
    def __init__(self, API):
        config = configparser.ConfigParser()
        config.read(os.path.dirname(__file__) + '/conf.ini')
        self.url = config.get(API, 'url')
        self.attribute = config.get(API, 'response')
        self.header = {'content-type': 'application/json'}

    def get(self):
        response = requests.get(self.url, headers=self.header)
        response = response.json()

        # Browse the response to fetch only the attributes you want
        self.attribute = self.attribute.split('.')
        depth = len(self.attribute)
        for i in range(depth):
            response = response[self.attribute[i]]

        print(response)
        return response

然后你可以在主脚本中叫你上课:

import bitcoin_api
result = bitcoin_api.BitcoinAPI('COINDESK').get()
result = bitcoin_api.BitcoinAPI('BITSTAMP').get()

答案 1 :(得分:1)

嗯,构建代码的理智方法包括超类(继承)和某种标准化(接口)。

假设我理解你的问题,你需要一个关于如何从各种交易所索取价格的标准。

所以考虑这个结构(当然它完全是草案):

import requests

class BitcoinAPI:

    def get_price_usd(self):
        raise NotImplementedError

    @staticmethod
    def generic_unothorized_request(request_method, url, **kwargs):
        return getattr(requests, request_method)(url, **kwargs)


class CoinDesk(BitcoinAPI):

    url = 'https://api.coindesk.com/v1/bpi/currentprice.json'

    def get_price_usd(self):
        return self.generic_unothorized_request('get', url)
        # process result, bla bla


class Bitstamp(BitcoinAPI):

    def get_price_usd(self):
        # Implementation of get_price_usd for Bitstamp
        return 0.0