Не получается вызвать статический метод класса в python

Класс topic, с вызовом метода из которого у меня возникают проблемы:

#.tools  - where definded get_current_time, generate_id
#db is object of class and have method excute_query, wich send query to
from .tools import *

class topic:
    
    def __init__(self,theme,author,about,db):
        self.time_of_creation = get_current_time
        self.theme = theme
        self.author = author
        self.about = about
        self.sb_id = generate_id()
        self.db = db

        try:
            #inserting data into DB
            self.db.excute_query(f"""INSERT INTO user VALUES ("{get_current_time()}, '{self.theme}', 
                                                            '{self.author}','{self.about}',
                                                            '{generate_id()}')""")
            
            return 1
    
        except Exception as e:
            print(str(e))
            return [0, str(e)]
        
    @staticmethod
    def all(self):
        return self.db.excute_query("SELECT * FROM topic")

Я пытаюсь вызвать метод all():

topic.all()

и в ответ получаю AttributeError: 'function' object has no attribute 'all'. Как мне это исправить?


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

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

Первый вариант — вместо статического метода используйте самостоятельную функцию. Для того

  1. Удалите строку

        @staticmethod
    
  2. Вместо параметра self (который вам нужен только для определения, с которой датабазой вы хотите работать), примените прямо параметр db

        def all_(db):
    

    Обратите внимание на то, что вместо имени all я применил имя all_, т.к. all является именем стандартной функции Питона.

  3. Удалите отступ перед этим определением функции — вам не нужно, чтобы она была связана с вашим классом topic, и соответственно уменьшите отступ следующей команды. Ну и в этой команде удалите часть self. и вместо topic примените имя вашей таблицы — из вашего кода я гадаю, что оно user:

    def all_(db):
        return db.excute_query("SELECT * FROM user")
    

Затем вы можете вызывать эту функцию в виде all_(имя_датабазы).


Второй вариант — исправите ваш статический метод. Для того отбросите self, т.к. статический метод не знает ничего ни об объекте, ни о классе. Значит,

вместо

    @staticmethod
    def all(self):
        return self.db.excute_query("SELECT * FROM topic")

используйте

    @staticmethod
    def all_(db):
        return db.excute_query("SELECT * FROM user")

Затем вы можете вызывать этот метод в виде topic.all_(имя_датабазы).

→ Ссылка
Автор решения: Алексей Р

По-моему, в данном случае может подойти метод класса (@classmethod):

class Topic:
    db = None

    def __init__(self, db):
        Topic.db = db

    @classmethod
    def select_all(cls):
        if cls.db:
            return f'Все данные из: {cls.db}'
        else:
            return 'Вы не указали БД'


print(Topic.select_all())
print(Topic('БазаДанных').select_all())
Вы не указали БД
Все данные из: БазаДанных
→ Ссылка