Почему возращаемый класс метод?

Я имею следующую систему классов:

import sqlite3
import psycopg2 as psql

from .user import user
from .message import *
from .topic import *
from .user import user
from .tools import *

class SQLite3:

    def __init__(self, path):
        self.path = path

    def work(self, query):
        con = sqlite3.connect(self.path)
        cursor = con.cursor()
        cursor.execute(query)
        data = cursor.fetchall()
        con.commit()

        return data
    
    def DBInit(self):
        InitDB(self.work)

class postgres():

    def __init__(self, host, port, name, user, password):
        self.host = host
        self.port = port
        self.name = name
        self.user = user
        self.password = password

    def work(self, query):
        conn = psql.connect(dbname=self.name, user=self.user, password=self.password, host=self.host, port=self.port)
        cursor = conn.cursor()
        cursor.execute(query)
        data = cursor.fetchall()
        cursor.close()
        conn.close()

        return data
    
    def DBInit(self):
        InitDB(self.work)


class DB:

    def __init__(self, DBType="sqlite3", path="", host="", port="", name="", user="", password=""):

        match DBType:
            case "sqlite3":
                self.db = SQLite3(path)
            case "postgres":
                self.db = postgres(host, port, name, user, password)
            case _:
                raise TypeError("Unkwon type of DB")
            

    def DBInit(self):
        self.db.DBInit()

    def User(self):
        return user(self.db.work)

    def Topic(self):
        return topic(self.db.work)

    def Message(self):
        return messages(self.db.work)

from .tools import *
from .TableMetaClass import *
from .storage import *

class messages(TableMetaClass):

    def __init__(self, DBworker):
        super().__init__(DBworker)

    def get(self, MessageId):
        super().get(self)

        return MessagesStorage(self.DBworker(f"SELECT * FROM messages WHERE MessageId = {MessageId}"))
    
    def JsonGet(self, MessageId):

        return {"TopicId":MessageId[0], "MessageId":MessageId[1], "author":MessageId[2], "text":MessageId[3], "time":MessageId[4]}

    def all_(self):
        super().get(self)

        return [MessagesStorage(i) for i in self.DBworker("SELECT * FROM messages")]
    
    def AllJson(self):

        return [{"TopicId":MessageId[0], "MessageId":MessageId[1], "author":MessageId[2], "text":MessageId[3], "time":MessageId[4]} for MessageId in self.DBworker("SELECT * FROM messages") ]

    def delete(self, MessageId):
        super().get(self)
        self.DBworker(f"DELETE * from messages WHERE MessageId = {MessageId}")

    def create(self, TopicId, author, text, time_of_publication):
        # TopicId, MessageId, author, text, time_of_publication
        super().create(self)
        
        try:
            self.DBworker(f"INSERT INTO messages VALUES '{TopicId}', '{generate_id()}', '{author}', '{text}', '{get_current_time()}'")
            return 1
        except:
            return 0

Когда я подобным образом вызывал метод GetViaTokenJson

db = DB(DBType="sqlite3",path="main.db")
db.User.GetViaTokenJson("AwesomeToken"

У меня возникает подобная ошибка: AttributeError: 'function' object has no attribute 'GetViaTokenJson' Почему DB возвращает не объект класса User, а метод?


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

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

db.User это метод User класса DB, что бы он исполнился и вернул свой результат его надо вызвать db.User().

Если лишние скобки для вызова метода (db.User().GetViaTokenJson()) лень писать каждый раз, то метод можно преобразовать в property, тогда функция будет вызываться под капотом при обращении как бы к обычному полю класса:

class DB:
    ...

    @property
    def User(self):
        return user(self.db.work)

И вот тогда можно будет обращаться более красиво, как db.User.GetViaTokenJson()

→ Ссылка