2017-10-15 9 views
1

J'ai importé un paquet cool (si c'est important, ça s'appelle tweepy).remplace le module python par un qui a un argument supplémentaire - python

Mais il y a une petite limitation avec 2 des méthodes en raison d'un récent changement Twitter fait. Il y a déjà un correctif mais il n'a pas été tiré depuis un certain temps

Je pensais essayer d'ajouter temporairement le correctif de mon côté et remplacer les modules existants jusqu'à ce que le paquet soit mis à jour, bien que je ne sois pas aussi expérimenté avec python

def statuses_lookup(self, id_, include_entities=None, 
        trim_user=None, map_=None): 
    return self._statuses_lookup(list_to_csv(id_), include_entities, 
           trim_user, map_) 

@property 
def _statuses_lookup(self): 
    """ :reference: https://dev.twitter.com/rest/reference/get/statuses/lookup 
     :allowed_param:'id', 'include_entities', 'trim_user', 'map' 
    """ 
    return bind_api(
     api=self, 
     path='/statuses/lookup.json', 
     payload_type='status', payload_list=True, 
     allowed_param=['id', 'include_entities', 'trim_user', 'map'], 
     require_auth=True 
    ) 

et en remplaçant que, avec une semblable (différence en ajoutant un tweet_mode argument supplémentaire pour autant que je sache):

def statuses_lookup(self, id_, include_entities=None, 
        trim_user=None, map_=None, tweet_mode=None): 
    return self._statuses_lookup(list_to_csv(id_), include_entities, 
           trim_user, map_, tweet_mode) 

@property 
def _statuses_lookup(self): 
    """ :reference: https://dev.twitter.com/rest/reference/get/statuses/lookup 
     :allowed_param:'id', 'include_entities', 'trim_user', 'map', 'tweet_mode' 
    """ 
    return bind_api(
     api=self, 
     path='/statuses/lookup.json', 
     payload_type='status', payload_list=True, 
     allowed_param=['id', 'include_entities', 'trim_user', 'map', 'tweet_mode'], 
     require_auth=True 
    ) 

Je n'ai jamais vraiment essayé quelque chose comme ça avant en python 3.X

+0

Quelle est la question? –

+0

@SergeyVasilyev, est-il possible de remplacer les méthodes existantes dans l'importation (premier bloc de code), avec la version modifiée (deuxième bloc de code) – user3120554

+0

puisque la différence est juste un autre argument. Je pensais simplement ajouter l'altération dans mon code devrait être suffisant (polymorphisme liaison tardive selon ma compréhension), mais alors je ne sais pas comment cela s'applique aux importations – user3120554

Répondre

0

Dans ce cas, la meilleure façon de mettre en œuvre étend de l'objet d'origine et en remplaçant ce que vous voulez:

class CustomAPI(API): 
    def statuses_lookup(self, id_, include_entities=None, 
        trim_user=None, map_=None, tweet_mode=None): 
     return self._statuses_lookup(list_to_csv(id_), include_entities, 
           trim_user, map_, tweet_mode) 

    @property 
    def _statuses_lookup(self): 
     """ :reference: https://dev.twitter.com/rest/reference/get/statuses/lookup 
      :allowed_param:'id', 'include_entities', 'trim_user', 'map', 'tweet_mode' 
     """ 
     return bind_api(
      api=self, 
      path='/statuses/lookup.json', 
      payload_type='status', payload_list=True, 
      allowed_param=['id', 'include_entities', 'trim_user', 'map', 'tweet_mode'], 
      require_auth=True 
     ) 

Ensuite, vous pouvez utiliser CustomAPI au lieu de API.

Mise à jour

Supposons que vous créez un nouveau fichier custom_tweepy.py:

from tweepy import API 

class CustomAPI(API): 
    def statuses_lookup(self, id_, include_entities=None, 
        trim_user=None, map_=None, tweet_mode=None): 
     return self._statuses_lookup(list_to_csv(id_), include_entities, 
           trim_user, map_, tweet_mode) 

    @property 
    def _statuses_lookup(self): 
     """ :reference: https://dev.twitter.com/rest/reference/get/statuses/lookup 
      :allowed_param:'id', 'include_entities', 'trim_user', 'map', 'tweet_mode' 
     """ 
     return bind_api(
      api=self, 
      path='/statuses/lookup.json', 
      payload_type='status', payload_list=True, 
      allowed_param=['id', 'include_entities', 'trim_user', 'map', 'tweet_mode'], 
      require_auth=True 
     ) 

Puis tout autre endroit que vous utilisez à l'origine from tweepy import API, vous pouvez le remplacer par from custom_tweepy import CustomAPI as API. Ensuite, vous pouvez utiliser votre implémentation d'API personnalisée. Et, vous venez de remplacer ces deux fonctions afin que toutes les autres fonctions ne soient pas modifiées du tout.

+0

Si j'utilise customapi au lieu d'api, cela ne signifie-t-il pas que je dois modifier le code de l'import pour inclure la classe? sinon tweepy.API ne serait pas remplacé par tweepy.CusomAPI – user3120554

+0

Je veux aussi conserver la fonctionnalité des autres méthodes dans l'API. en effet imiter le comportement d'aller dans le code source et de changer directement le code – user3120554

+0

Non, vous n'avez pas besoin de modifier le code source. Vous pouvez simplement créer un nouveau fichier qui inclut 'from tweepy import API' et votre' CustomAPI'. Ensuite, vous pouvez remplacer 'from tweepy import API' par' from_file import CustomAPI as API' pour utiliser votre 'CustomAPI'. En outre, dans ce cas, vous venez de remplacer ces deux fonctions, d'autres ne sont pas modifiées du tout. Je vais mettre à jour ma réponse pour la rendre plus explicite. – Sraw

1

Tout est faisable.

Voici la solution simplifiée pour pirater une classe. Même si le module a été importé, et la classe a été utilisé pour créer un objet - ce hack affectera tous les objets existants immédiatement:

class KLS(object): 
    @property 
    def x(self): 
     print('OLD') 
     return 100 

def new_function(self): 
    print('NEW') 
    return 200 

obj = KLS() 

print(obj.x) # OLD + 100  
KLS.x = property(new_function) # <-- HACK! 
print(obj.x) # NEW + 200 

La solution fonctionne aussi bien pour py2 & PY3.

Cependant, assurez-vous qu'il n'y a pas de setters/deleters pour cette propriété dans la classe d'origine (c'est-à-dire, est-ce réglable ou simplement en lecture seule?) Pour les setters, vous devrez appeler property(getter_func, setter_func).

+0

hmm je pensais à quelque chose de similaire via tweepy.API._statuses_lookup = _statuses_lookup2 et tweepy.API.statuses_lookup = statuses_lookup2. J'ai essayé avec la propriété(), bien que j'aie une erreur: statuses_lookup2() manquant 1 argument positionnel requis: 'id_' – user3120554

+0

Tout ce que j'appelle vraiment est: api = tweepy.API (auth) ((((où les changements ci-dessus ont déjà été faits))))) et les tweets = api.statuses_lookup (id_batch, tweet_mode = 'extended') – user3120554