При желании используйте декораторы для методов класса

Я новичок в Python и создаю оболочку для API. Я бы хотел, чтобы пользователь сам решал, хочет ли он использовать декоратор для методов, которые я выставляю из своего модуля.

Например:

# create a new instance
api = MyApi()

# return a simple json response with all the data related to a timetable
print api.time_table

Теперь у пользователя есть все данные, и он может делать все, что захочет. Например, я хотел бы добавить какие-то «удобные» методы; чтобы позволить пользователю получить небольшую часть json вместо всего большого ответа json.

Моя идея заключалась в том, чтобы использовать для этого декораторы Python. При желании моя цель может быть примерно такой:

# use the method and get al the data
print api.time_table

# Optionally, get a specific part, just the shows part. (PSEUDO CODE BELOW)
@shows
print api.time_table

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

Итак, каков самый питонический способ здесь? Я действительно хотел бы использовать декоратор, но если это плохая идея, я могу просто создать больше «удобных» методов внутри моего класса Api.


person stormpat    schedule 29.03.2014    source источник
comment
Вы можете использовать декораторы только для функций и классов, а не для чего-либо еще (например, операторов print). Вместо этого вы расширите свой API, чтобы предоставить пользователю больше возможностей.   -  person Martijn Pieters    schedule 29.03.2014
comment
Спасибо за быстрый ответ, так что нет возможности использовать декораторы для СУЩЕСТВУЮЩИХ функций? В этом случае мне придется использовать больше методов класса. Может быть, я придумаю что-нибудь удобное, используя лямбда-выражения.   -  person stormpat    schedule 29.03.2014
comment
Конечно, вы тоже можете использовать декораторы; декораторы — это просто функции; @foo применительно к bar точно совпадает с bar = foo(bar); замена bar возвращаемым значением foo при вызове с bar в качестве аргумента.   -  person Martijn Pieters    schedule 29.03.2014


Ответы (1)


Вы можете добавить больше методов в свой API или вместо этого предоставить пользователю служебные функции:

from yourmodule import MyAPI

api = MyAPI

filtered_timetable = api.filter_on(something)

or

from yourmodule import MyAPI, filter_timetable

api = MyAPI

filtered_timetable = filter_timetable(api.time_table, something)

Помните, что декораторы — это просто вызываемые объекты; синтаксис:

@foo
def bar():
    pass

это просто синтаксический сахар для:

def bar():
    pass
bar = foo(bar)

foo() вызывается, и возвращаемое значение заменяет декорированный объект. Обычно вы используете функции для декораторов, но ничто не говорит, что вы должны использовать эти функции только в качестве декораторов.

filter_timetable мог быть таким декоратором; если у вас есть возможность использовать его как оба.

person Martijn Pieters    schedule 29.03.2014