2012-08-03 11 views
2

Модуль Twython использует внутренний модуль запросов.Я хочу украсить метод в классе, но без редактирования class.py - подробности внутри

Я хочу, чтобы обернуть/украсить запрос requests.post(*k, **kw), так что все, что Twitton делает request.post(...), будет его прозрачно оформлять/обертывать без вмешательства в модуль Twython.

Если я отредактировал кодовую базу запросов, которая была бы достаточно легкой, но мне любопытно, как решить общую проблему добавления декоратора к уже определенному функции/методу.

import requests 
def magic_wrapper_doodad(...) 
... 
... 
requests.post = magic_wrapper_doodad(my_function, requests.post) # plz? 

import Twython 

# thanks to the above magic, requests.post is wrapped just as if it was defined like: 
@decorator 
def trace(f, *args, **kw): 
    print("calling %s with args %s, %s" % (f.__name__, args, kw)) 
    return f(*args, **kw) 

... 
... #inside requests.py now: 
@trace 
def post(self, *args, **kw): 
... 

как я пишу magic_wrapper_doodad() - или какой-либо альтернативный код - так что я могу украсить код, как это?

ответ

5

Декоратор @ обозначение - это просто синтаксический сахар для вызова декоратора, вызываемого с украшенной функцией и заменяющего украшенную функцию результатом.

Другими словами, следующие два примера точно такую ​​же вещь:

@yourdecorator 
def a_function(): 
    pass 

def b_function(): 
    pass 
b_function = yourdecorator(b_function) 

и то же самое относится и к методам определения классов.

Таким образом, вы можете просто украсить метод класса, заменив метод класса с результатом декоратор отзывной:

requests.post = my_function(requests.post) 

Это то же самое, как если бы вы написали:

class requests(object): 
    @my_function 
    def post(self, *args): 
     pass 

Обратите внимание, что в вашем случае requests фактически является модулем, а не классом, но применяются те же принципы.

+0

s/request/requests – jterrace

+0

@jterrace: символы 's' введены должным образом. –

+0

запросы - это модуль, хотя и не класс. +1 – jterrace

2

Martijn Pieters' answer является способ пойти, если вам нужно украсить функцию запросов. Я просто подумал, что я бы сказал, что на самом деле у запросов есть a mechanism for hooks.

Если вы можете сделать то, что вам нужно сделать с помощью крючка, вам следует. Это чище, чем исправление обезьяны.

+0

Я знаю о крючках, есть несколько разных причин, по которым я хочу украсить вызовы 'request', одним из которых было автоматическое добавление крючков в запрос. Как это идеально было бы сделать без украшения методов 'request.get' /' request.post' или изменения кода 'Twython'? –