Это расширение Динамически декорировать функцию внутри класса в Python3
@ MisterMyagi правильно ответил на мой вопрос, что вы можете динамически декорировать класс с помощью этой логики:
class MyTaskSequence(TaskSequence):
pass
def add_sequence(cls, order, path):
@seq_task(order)
def sequence(self):
self.client.get(path)
sequence.__name__ = "sequence%d" % order
setattr(cls, sequence.__name__, sequence)
add_sequence(MyTaskSequence, 1, "/devops/")
add_sequence(MyTaskSequence, 2, "/blog/")
Мой вопрос таков: как вы гарантируете, что сгенерированная функция может одновременно использоваться как автономная функция и как метод класса?
Например: определение статической функции:
class MyTaskSequence(TaskSequence):
@seq_task(1)
def sequence1(self):
self.client.get("/devops/")
@seq_task(2)
def sequence2(self):
self.client.get("/blog/")
pprint(vars(MyTaskSequence))
>>>>
mappingproxy({'__doc__': None,
'__module__': 'run-loadtest.index',
'sequence1': <function start.<locals>.MyTaskSequence.sequence1 at 0x10d759c20>,
'sequence2': <function start.<locals>.MyTaskSequence.sequence2 at 0x10d759f80>,
'tasks': [<function start.<locals>.MyTaskSequence.sequence1 at 0x10d759c20>,
<function start.<locals>.MyTaskSequence.sequence2 at 0x10d759f80>]})
То, что я пробовал:
class MyTaskSequence(TaskSequence):
pass
def add_sequence(cls, order, path):
@seq_task(order)
def sequence(self):
self.client.get(path)
sequence.__name__ = "sequence%d" % order
setattr(cls, sequence.__name__, sequence)
add_sequence(MyTaskSequence, 1, "/devops/")
add_sequence(MyTaskSequence, 2, "/blog/")
pprint(vars(MyTaskSequence))
>>>>
mappingproxy({'__doc__': None,
'__module__': 'run-loadtest.index',
'sequence1': <function start.<locals>.add_sequence.<locals>.sequence at 0x10590bc20>,
'sequence2': <function start.<locals>.add_sequence.<locals>.sequence at 0x10590bf80>,
'tasks': []})
Обратите внимание, что результирующий объект немного "отличается".
Теперь я понимаю, что это вызвано библиотекойчто я использую, но в настоящее время у меня сложилось впечатление, что это в основном вызвано тем фактом, что сгенерированная функция «sequence% d» является просто автономной функцией, а не методом класса.
Youможно проверить это, сравнив полученное «определение» двух отпечатков:
'sequence1': <function start.<locals>.MyTaskSequence.sequence1 at 0x10d759c20>,
VERSUS
'sequence1': <function start.<locals>.add_sequence.<locals>.sequence at 0x10590bc20>,
PS: обратите внимание на отсутствующее имя класса в его определении.