В настоящее время у меня есть декоратор, который обертывает функцию в класс.Использование декоратора, возвращающего класс по методу?
(настоящее время мы используем эту странную, структуру пользовательских асинхронной где каждый асинхронной вызов определяется как класс с тонны шаблонного кода. Моя идея состояла в том, чтобы просто украсить функции, а затем вернуть соответствующий класс.)
Этот декоратор отлично работает над функциями вне классов. Однако при использовании его с методами аргумент self
уже неявно передается, и я не уверен, почему.
Вот лучший пример, который я не мог собрать
from __future__ import print_function
import functools
def test_wrap(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
print("Args:", args)
print("Kwargs:", kwargs)
func(*args, **kwargs)
return wrapper
def test_class_wrap(func):
"""Return a Command object for use with the custom framework we are using."""
@functools.wraps(func, assigned=('__name__', '__module__'), updated=())
class Command(object):
def __init__(self, *args, **kwargs):
print("Args:", args)
print("Kwargs:", kwargs)
func(*args, **kwargs)
return Command
class MyObject(object):
def __init__(self):
self.value = 100
@test_wrap
def foo(self):
print(self.value)
@test_class_wrap
def bar(self):
print(self.value)
if __name__ == '__main__':
obj = MyObject()
obj.foo()
print()
obj.bar(obj) # works
# obj.bar() # TypeError: bar() takes exactly 1 argument (0 given)
# Why is self implicitly passed as an argument like with outher methods?
# Output
# Args: (<__main__.MyObject object at 0x7fe2bf9bb590>,)
# Kwargs: {}
# 100
# Args: (<__main__.MyObject object at 0x7fe2bf9bb590>,)
# Kwargs: {}
# 100
Хорошо. , , подумайте, как это будет работать, если вы сделали это вручную. Без декоратора вы пишете код, в котором один класс вложен внутри другого? Если да, то как вы это сделали? Классы - это не методы, поэтому, если у вас есть декоратор, который заменяет метод классом, у вас будет класс внутри вашего другого класса, что несколько необычно для Python. Можете ли вы показать пример того, как вы будете писать «MyObject» и «bar» вручную », не используя декоратор? – BrenBarn
Этот вопрос более сфокусирован на том, почему 'self' неявно передается' bar'. Приведенный выше код реплицирует проблему, а не фактическое использование. Я могу попытаться добавить пример, но не ожидаю, что это будет иметь смысл. – Shatnerz
Причина self не передана, потому что нет экземпляра вашего класса. 'self' относится к экземпляру, поэтому его можно передавать только при вызове метода в экземпляре, но ваш' obj.bar' является * классом *, называемым 'Command'. Если вы написали этот класс Command отдельно и попытались вызвать 'Command()', вы получите ту же ошибку. – BrenBarn