Почему я не могу использовать @staticmethod здесь? - PullRequest
2 голосов
/ 04 марта 2020

Я использую django -fsm для реализации конечного автомата. Код выглядит как

def user_ok_to_check_me( instance, user):
    ... 

class Job( models.Model):

# ... many screenfulls of code

    @transition( field=state,  target=BOOKING, source=CHECKING, permission=user_ok_to_check_me)
    def fail_checking(self, **kwargs):
    ...

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

class Job( models.Model):

    # ... many screenfulls of code

    @staticmethod
    def user_ok_to_check_me( instance, user):
        ... 
    @transition( field=state,  target=BOOKING, source=CHECKING, permission=user_ok_to_check_me)
    def fail_checking(self, **kwargs):

, который не работает. Не уверен, что теперь делает user_ok_to_check_me, он ведет себя как неактивная функция, всегда возвращающая True, даже когда все это return False

Почему? И есть ли способ объявить эту маленькую функцию внутри класса? (Это слишком долго, чтобы использовать lambda instance, user:)

1 Ответ

0 голосов
/ 10 марта 2020

Нашли ответ, хотя я не уверен, что понимаю его.

class Job( models.Model):

    # ... many screenfulls of code

    # @staticmethod  #NO DECORATOR
    def user_ok_to_check_me( instance, user):
    ... 
    @transition( field=state,  target=BOOKING, source=CHECKING, permission=user_ok_to_check_me)
    def fail_checking(self, **kwargs):

Использование ok_to_check_me в @transition происходит во время выполнения кода, который создает класс, а не во время его создания. Так что нужна ссылка на фактическую функцию, определенную выше. Применение @staticmethod к этой функции заменяет ее чем-то другим, и что бы это ни было, неприемлемо для декоратора перехода.

Когда создается экземпляр класса, функция связывается с экземпляром. Это, однако, не влияет на ссылку на функцию, которая @transition уже сохранена во внутренних органах. В этом случае привязка безвредна, поскольку instance и self обычно относятся к одному и тому же. В других случаях может потребоваться удалить непреднамеренную связанную функцию из экземпляра в ее методе __init__ (или просто тщательно документировать, чтобы не пытаться использовать ее в качестве метода объекта).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...