Python:未初始化Database类时如何在Host类中调用其数据库方法
解决Host类中调用Database实例方法的问题
问题核心
你当前的问题在于Host类的__init__方法中仅将Database类本身赋值给self.db,而非创建Database的实例对象。select是实例方法,必须通过Database的实例才能调用,直接通过类调用会报错。
解决方案步骤
正确初始化Database实例
在Host的初始化方法中,需要传入数据库连接参数(主机、库名、用户名、密码),并以此创建Database的实例,赋值给self.db。修复Database类的连接管理
原select方法每次调用后会关闭数据库连接,导致后续无法复用该实例。建议移除self.con.close(),改为提供手动关闭连接的方法,在Host实例销毁时统一关闭。实现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
相关产品推荐
相关产品推荐

