Уведомления

Группа в Telegram: @pythonsu

#1 Апрель 18, 2011 13:02:22

Андрей Светлов
От:
Зарегистрирован: 2007-05-15
Сообщения: 3137
Репутация: +  14  -
Профиль   Адрес электронной почты  

Как применить декоратор ко всем пользовательским методам

1. http://python.org/dev/peps/pep-3129/
2. Дерево вызовов? Мы одно и то же подразумеваем под “логированием”? Для меня это помимо всего прочего использование инфраструктуры стандартного пакета logging.



Офлайн

#2 Апрель 18, 2011 13:33:38

kl
От:
Зарегистрирован: 2011-04-18
Сообщения: 6
Репутация: +  0  -
Профиль   Отправить e-mail  

Как применить декоратор ко всем пользовательским методам

1. да, спасибо, тоже попробовал уже и такой синтаксис. буду разбираться во внутренностях.
2. logging используем. на выходе несколько видов логов, в том числе иерархический (на java-script кажется) html.
по нему приблизительно видно дерево вызовов и что творится внутри них.
не описывать же всевозможные применения логов…



Офлайн

#3 Апрель 20, 2011 13:40:44

shupg
От:
Зарегистрирован: 2009-08-07
Сообщения: 25
Репутация: +  0  -
Профиль   Отправить e-mail  

Как применить декоратор ко всем пользовательским методам

каким образом, флаг _throw_exc_on_False или любой другой можно передать
class LoggedClass(type):
def __call__(cls, *args, **kargs):

if hasattr(cls, '_throw_exc_on_False'):
print getattr(cls, '_throw_exc_on_False')
return type.__call__(cls, *args, **kargs)

class CustomClass(object):
__metaclass__ = LoggedClass
_throw_exc_on_False = True

CustomClass()



Офлайн

#4 Апрель 21, 2011 07:50:53

kl
От:
Зарегистрирован: 2011-04-18
Сообщения: 6
Репутация: +  0  -
Профиль   Отправить e-mail  

Как применить декоратор ко всем пользовательским методам

shupg
каким образом, флаг _throw_exc_on_False или любой другой можно передать
class LoggedClass(type):
def __call__(cls, *args, **kargs):

if hasattr(cls, '_throw_exc_on_False'):
print getattr(cls, '_throw_exc_on_False')
return type.__call__(cls, *args, **kargs)

class CustomClass(object):
__metaclass__ = LoggedClass
_throw_exc_on_False = True

CustomClass()
спасибо большое!
есть ли еще возможность контролировать применение декоратора
только к методам данного конкретного класса CustomClass?
в моей ситуации декоратор применяется еще к CustomClassBase,
что часто не является желательным.

class LoggedClass(type):
def __call__(cls, *args, **kargs):
return type.__call__(cls, *args, **kargs)

class CustomClass(CustomClassBase, object):
__metaclass__ = LoggedClass
_throw_exc_on_False = True

CustomClass()



Офлайн

#5 Апрель 21, 2011 08:03:26

Андрей Светлов
От:
Зарегистрирован: 2007-05-15
Сообщения: 3137
Репутация: +  14  -
Профиль   Адрес электронной почты  

Как применить декоратор ко всем пользовательским методам

То, что вы написали — называется метаклассом, а не декоратором.
Избирательно метакласс не применяется. Зато внутри него в __init__/__new__ можно посмотреть, какой класс создается.
Если я правильно расшифровал вопрос. Это очень хитрый ход: говорить о CustomClassBase, не показывая его исходник при этом.



Офлайн

#6 Апрель 21, 2011 09:13:11

kl
От:
Зарегистрирован: 2011-04-18
Сообщения: 6
Репутация: +  0  -
Профиль   Отправить e-mail  

Как применить декоратор ко всем пользовательским методам

Понимаю, что это метакласс и в терминах python-а от декоратора он отличается,
но когда имеется ввиду шаблон декоратор, то смысл похож.
Python богат на технические трюки.
Вот я и интересуюсь нельзя ли сделать так,
чтобы действие метакласса не распространилось
на базовые классы, независимо от их содержания,
в случае когда необходимо и достаточно
применить его лишь к данному конкретному классу.
Если быть более точным, мне интересна возможность
декорирования только методов данного конкретного класса,
возвращающих только bool (True/False), что должно отличаться,
например, от просто целочисленного 0.

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

Везде много примеров кода декоратора именно для функции в стиле

def decorator(f):
def func(*args, **kargs):
print 'executing %s...' % f.__name__
return f(*args, **kargs)
return func
но как должен выглядеть код декоратора применяемого к классу,
мне найти не удалось, поэтому сначала я пошел по пути метакласса.

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



Офлайн

#7 Апрель 21, 2011 09:31:57

Андрей Светлов
От:
Зарегистрирован: 2007-05-15
Сообщения: 3137
Репутация: +  14  -
Профиль   Адрес электронной почты  

Как применить декоратор ко всем пользовательским методам

kl
Если быть более точным, мне интересна возможность
декорирования только методов данного конкретного класса,
возвращающих только bool (True/False), что должно отличаться,
например, от просто целочисленного 0.
Это как? Тип возвращаемого значения — динамически определяется. Что вернете, то и будет. В момент вызова.
А декорирование — в момент создания класса. Методы перечислить можно, но что они вернут без дополнительных аннотаций — никак.
Динамическая типизация все же.

Остальные вопросы меркнут по сравнению с мировой революцией.

ki, вы бы не стеснялись. Изложите задачку, с иллюстрацией на предметной области. Может, вам вообще вся эта машинерия не нужна?
Если просто хотите “на каждый False бросить exception” — так бросайте, зачем декораторы городить.

А то не покидает чувство, что для сферического вакуумного коня изобретаем корм из светоносного эфира.



Офлайн

#8 Апрель 21, 2011 10:22:49

pyuser
От:
Зарегистрирован: 2007-05-13
Сообщения: 658
Репутация: +  36  -
Профиль   Отправить e-mail  

Как применить декоратор ко всем пользовательским методам

kl
Везде много примеров кода декоратора именно для функции в стиле
Плохо искали :(. вот например.



Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version