You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python:未初始化Database类时如何在Host类中调用其数据库方法

解决Host类中调用Database实例方法的问题

问题核心

你当前的问题在于Host类的__init__方法中仅将Database类本身赋值给self.db,而非创建Database的实例对象。select是实例方法,必须通过Database的实例才能调用,直接通过类调用会报错。

解决方案步骤

  1. 正确初始化Database实例
    在Host的初始化方法中,需要传入数据库连接参数(主机、库名、用户名、密码),并以此创建Database的实例,赋值给self.db。

  2. 修复Database类的连接管理
    原select方法每次调用后会关闭数据库连接,导致后续无法复用该实例。建议移除self.con.close(),改为提供手动关闭连接的方法,在Host实例销毁时统一关闭。

  3. 实现check_hostname方法
    通过self.db.select()执行查询,处理返回的结果集(fetchall()返回元组列表),提取主机名字段后进行存在性判断。

完整代码示例

import socket
import psutil
import time
import psycopg2

class Database:
    """Class to connect with the desired DB"""

    def __init__(self, host, database, user, password):
        self.con = psycopg2.connect(
            host=host,
            database=database,
            user=user,
            password=password
        )

    def select(self, query):
        cur = self.con.cursor()
        cur.execute(query)
        fetched_selects = cur.fetchall()
        cur.close()
        # 移除此处的连接关闭,避免后续调用失效
        # self.con.close()
        return fetched_selects
    
    def close(self):
        """手动关闭数据库连接"""
        if hasattr(self, 'con') and not self.con.closed:
            self.con.close()

class Host:
    def __init__(self, db_host, db_name, db_user, db_password):
        # 初始化Database实例,传入连接参数
        self.db = Database(db_host, db_name, db_user, db_password)
        self.hostname = socket.gethostname()
        self.cores = psutil.cpu_count(logical=True)
        self.total_RAM = f'{psutil.virtual_memory()[0] / 1024 ** 3:.2f}'
        self.uptime = int(time.time() - psutil.boot_time())
        self.free_ram = f'{psutil.virtual_memory()[4] / 1024 ** 3:.2f}'
        self.disk_usage = psutil.disk_usage('/')

    def check_hostname(self):
        # 替换为你的实际查询语句,确保返回主机名字段
        query = "SELECT hostname FROM hosts;"
        db_results = self.db.select(query)
        # 从元组列表中提取主机名字符串
        db_hostnames = [item[0] for item in db_results]
        
        if self.hostname in db_hostnames:
            # 主机名存在的业务逻辑
            print(f"主机名 {self.hostname} 已存在于数据库")
            return True
        else:
            # 主机名不存在的业务逻辑
            print(f"主机名 {self.hostname} 未在数据库中找到")
            return False
    
    def __del__(self):
        # 销毁Host实例时自动关闭数据库连接
        self.db.close()

# 使用示例
if __name__ == "__main__":
    # 替换为你的实际数据库连接信息
    my_host = Host(
        db_host="localhost",
        db_name="your_database",
        db_user="your_user",
        db_password="your_password"
    )
    my_host.check_hostname()

关键说明

  • 实例化Database时必须传入连接参数,这是__init__方法的强制要求,确保数据库连接成功建立。
  • 处理查询结果时,fetchall()返回的是形如[(hostname1,), (hostname2,)]的元组列表,需要通过列表推导式提取出实际的主机名字符串。
  • 添加__del__方法和Database.close()方法,确保数据库连接在实例生命周期结束时被正确关闭,避免资源泄漏。

内容的提问来源于stack exchange,提问作者ACNiC03

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 23:15:23