Skip to main content
 首页 » 编程设计

python之实现 Django 风格的 API,链接点,继承

2024年10月17日34webabcd

我正在尝试为 JSON API 实现客户端。我使用过 Django,我发现它处理查询的方式非常有趣。

例如:

>>> from django.contrib.auth.models import User 
>>> user = User.objects.get(username='johndoe') 
>>> user 
<User: johndoe> 
>>> user.objects.get(username='johndoe') 
AttributeError: Manager isn't accessible via User instances 

我感兴趣的是 Manager 到底是什么,以及是否有一种简单的方法来实现它。我试图做类似的事情,但惨遭失败。这是我的第一次尝试:

class Api(object): 
    def __init__(self, api_key): 
        self.api_key = key 
 
    @property 
    def player(self): 
        return Player(api=self) 
 
class Player(object): 
    def __init__(self, api): 
        self.api = api 
 
    def get(self, id_): 
        ''' 
        gets json and turns it into dictionary 
        ''' 
        self.name = data['name'] 
        self.id_ = id_ 
 
        return self 

所以用法看起来像这样:

>>> api = Api('api_key_here') 
>>> player = api.player.get('player_id_here') 

但是对我来说,这样做感觉粗略而且完全错误(这当然是真的)。这里的问题是:

  1. 我必须将整个 Api 对象发送到 Player 对象
  2. Player 对象仍然有 get() 方法
  3. 我不知道这样使用@property是否可以接受

这是我想如何使用我的 Api 类:

api = Api('api_key_here') 
player = api.player.get('player_id') #getting player object 
item = api.item.get('item_id') #getting item object 
recent_games = api.recent_games.filter(player=player, how_many=10) #getting list of game objects 

请您参考如下方法:

我推荐你看看https://github.com/samgiles/slumber它实现了你可能正在做的事情(一个 Rest API 客户端)。但是,即使您正在做其他事情, sleep 也会执行您正在尝试做的事情。像这样的东西:

class RestResource(object): 
 
    def __init__(self, *args, **kwargs): 
       self._store = kwargs 
 
    def __call__(self, id=None, action=None): 
       """ 
       Returns a new instance of self modified by one or more of the available 
       parameters. These allows us to do things like override format for a 
       specific request, and enables the api.resource(ID).get() syntax to get 
       a specific resource by it's ID. 
       """ 
 
       kwargs = { 
          'foo': self._store['name1'], 
          'bar': self._store['name2'] 
       } 
 
       return self.__class__(**kwargs) 
 
class Api(object): 
   resource_class = RestResource 
 
   def __getattr__(self, item): 
      kwargs = { 
        'name1': 'val1', 
        'name2': 'val2' 
      } 
 
      return self.resource_class(**kwargs) 

你可以这样使用

api = Api() 
api.player.get()