@FOUREX

Почему у двух разных функций одинаковые ссылки?

def message_command(**kwargs):  # Декоратор
    def wrapper(function):
        function.message_command_kwargs = kwargs
        function.command = kwargs["command"]

        if kwargs["args"]:
            function.args = kwargs["args"]

        return function

    return wrapper


class Aliases:
    @property
    def commands(self) -> tuple:
        return (
            self.new_alias, self.aliases
        )

    @message_command(
        command="...",
        args={},
        usage="",
        description=""
    )
    async def new_alias(self, message: Message):
        ...

    @message_command(
        command="",
        args={},
        description=""
    )
    async def aliases(self, message: Message):
        ...


def setup(bot: Bot, dp: Dispatcher):
    aliases = Aliases(bot)
    print(aliases.commands)


Вывод в консоль:
(<\bound method Aliases.new_alias of <\aliases.py.Aliases object at 0x7fcf55c104c0>>, <\bound method Aliases.aliases of <\aliases.py.Aliases object at 0x7fcf55c104c0>>)


Проблема в том, что у двух функций, одинаковые адреса, как это испаравить, и почему это случилось?

мне нужно пройтись циклом по этим методам которые возвращает функция commands

for function in aliases.commands:
    dp.register_message_handler(function, lambda message: command_check(message, function.command))


Но так как адреса одинаковые, работает всё не так как нужно.
Как я тогда могу получить адрес каждой функции?
  • Вопрос задан
  • 76 просмотров
Решения вопроса 1
Vindicar
@Vindicar
Распарси скобки в выводе корректно, и загадка исчезнет.
<\bound method Aliases.new_alias of 
    <\aliases.py.Aliases object at 0x7fcf55c104c0>
>

Два разных метода одного объекта (с одним адресом).

И да, имей ввиду, что если ты берешь адрес метода на экземпляре объекта - ты получаешь не адрес функции в классе, а адрес специального объекта-обёртки bound method, который эту функцию привязывает к конкретному экземпляру класса. Иными словами:
import inspect

class A:
    def test(self, x):
        print(x)

a = A()
print(A.test)  # <function A.test at 0x0000029692C0FB50>
print(a.test)  # <bound method A.test of <__main__.A object at 0x0000029692BF3040>>
print(inspect.signature(A.test))  # <Signature (self, x)>
print(inspect.signature(a.test))  # <Signature (x)> так как значение self зафиксировано - это a
# причём обёртка создаётся каждый раз новая, это НЕ один и тот же объект
print(a.test is a.test)  # False
# но две обёртки одного метода равны.
print(a.test == a.test)  # True
# а метод класса всегда один и тот же
print(A.test is A.test)  # True
print(A.test == A.test)  # True
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы