Форум сайта python.su
Столкнулся с проблемой, что при декорировании метода класса с помощью декоратора вида:
class Dec: def __init__(self, func): self.func = func # self.__call__ = wraps(self.func)(self.__call__) def __call__(self, *args, **kwargs): return self.func(*args, **kwargs) @Dec def func(arg, kwarg=1): print('func. arg =', arg, 'kwarg =', kwarg) return class Test: def __init__(self): self.attr = 1 @Dec def func(self, arg, kwarg=1): print('Test.func. arg =', arg, 'kwarg =', kwarg, 'self.attr = ', self.attr) return func(1) func(1, 3) obj = Test obj.func(1) obj.func(1, 3)
Офлайн
нашел магию, которая сработала.
Объясните, пожалуйста, что это и как работает?)
def __get__(self, instance, instancetype): """Implement the descriptor protocol to make decorating instance method possible. """ # Return a partial function with the first argument is the instance # of the class decorated. return functools.partial(self.__call__, instance)
Офлайн
так, в общем чуть-чуть механику я понял, что при вызове функции через инстанцию (self) мы получаем call с добавленным аргументом self.
При этом, можно пользоваться классом декоратора через класс (class.function.attribute). Для этого надо ввести проверку на None:
if instance is None: return self
Отредактировано Levitanus (Июль 17, 2018 01:16:44)
Офлайн
Чтобы пользоваться декораторами (создавать их, а потом использовать), нужно освоить паттерн ООП “Декоратор”. А чтобы использовать паттерны ООП, нужно в само ООП углубиться неслабо, чтобы чувствовать его преимущество перед простыми функциями. В ООП есть три кита, на которых оно стоит, - инкапсуляция, наследование, полиморфизм. Вот паттерн декоратор - это одно из средств для реализации полиморфизма в программе.
Так что твои ковыряния в декораторах - это как ковыряния маленького мальчика в компонентах термоядерной бомбы. Оно тебе просто не пригодится в ближайшее время (ближайшие несколько лет изучения программирования).
Отредактировано py.user.next (Июль 17, 2018 02:13:04)
Офлайн
> нашел магию, которая сработала. Объясните, пожалуйста, что это и как работает?)
Ты на дескрипторы наткнулся. Вот хорошее видео по этой теме
https://www.youtube.com/watch?v=niBn5obLTHw
Офлайн
Возвращаясь к теме:
кто работает в sublime text + anaconda (или использует в каком-то виде jedi), не сталкивались с таким?
from functools import wraps def Dec(f): @wraps(f) def wrapper(*a, inline=None, **kw): if inline: print(f'inlined {f}') return f(*a, **kw) return wrapper class Test: @Dec def foo(self, arg1, arg2): '''class method docstring''' print(f'self={self}, arg1={arg1}, arg2={arg2}') @Dec def foo(arg1, arg2): '''just foo docstring''' print(f'arg1={arg1}, arg2={arg2}') Test().foo(1, 2, inline=True) foo(1, 2) print(Test().foo.__doc__) print(foo.__doc__)
inlined <function Test.foo at 0x000001579FBEFC80>
self=<__main__.Test object at 0x000001579FA9D9B0>, arg1=1, arg2=2
arg1=1, arg2=2
class method docstring
just foo docstring
Прикреплённый файлы:
2018-08-19_04-11-48.png (9,5 KБ)
Офлайн