Список функций класса

Реализовывал некоторый класс и столкнулся с проблемой.

Поместил некоторые методы класса в список _rules. Когда в другом методе класса прохожусь по полю _rules (for rule in self._rules) и передаю в rule аргумент, Pycharm мне подсказывает, что

Unexpected argument(s) 
Possible callees: 
Some._only_forward(move: Move) 
Some._spawn(move: Move)
Some._long_move(move: Move)

Хотя методы у меня не статические. Неужели rule не знает методом какого класса он является?

Всем спасибо

class Some:
    def __init__(self, ...):
        ...

        self._rules = [
            self._only_forward,
            self._spawn,
            self._long_move,
        ]

    # RULES
    def _only_forward(self, move: Move) -> bool:
        ...

    def _spawn(self, move: Move) -> bool:
        ...

    def _long_move(self, move: Move) -> bool:
        ...


    def _is_valid_move(self, move: Move):
        for rule in self._rules:
            if not rule(move):
                return False

        return True


Ответы (1 шт):

Автор решения: insolor

Это предупреждение, в данном случае PyCharm просто не смог определить, что у вас в списке лежат методы с одним аргументом (скорее всего он увидел, что есть список методов, но не смог понять, что все методы в этом списке имеют одинаковую "сигнатуру"). Можно добавить к полю _rules аннотацию типа, в ней явно указать что лежит в этом поле, тогда это предупреждение исчезнет:

from typing import List, Callable


class Move:
    ...


class Some:
    def __init__(self):
        ...

        self._rules: List[Callable[[Move], bool]] = [
            self._only_forward,
            self._spawn,
            self._long_move,
        ]

    # RULES
    def _only_forward(self, move: Move) -> bool:
        ...
        return True

    def _spawn(self, move: Move) -> bool:
        ...
        return True

    def _long_move(self, move: Move) -> bool:
        ...
        return True

    def _is_valid_move(self, move: Move):
        for rule in self._rules:
            if not rule(move):
                return False

        return True


some = Some()
print(some._is_valid_move(Move()))

Без аннотации:

Без аннотации

С аннотацией:

С аннотацией

Другой вариант, можно добавить аннотацию к переменной rule внутри цикла:

def _is_valid_move(self, move: Move):
    for rule in self._rules:
        rule: Callable[[Move], bool]
        if not rule(move):
            return False

    return True
→ Ссылка