python类的初始化

问题描述

存在这样的两个类,都在同一个模块a.py内

class YamlGlobal:
    with open(get_project_path() + "/cfg/global.yaml", 'r', encoding='utf-8') as f:
        glVar = yaml.load(f, Loader=yaml.SafeLoader)
    ......

class DatabaseGlobal:
    itd = InstanceDao(SQLAlchemyConnect())
    ......

# 原文链接:https://blog.csdn.net/qq_33562122/article/details/135380208
# 作者:秋不溜啾
# 未经许可,不得转载

同时存在一个b.py

from dao.get_global import YamlGlobal

if __name__ == "__main__":
    YamlGlobal()

当MySQL服务正常时,b.py是正常的,但当MySQL服务终止后,b.py执行时会出现“[WinError 10061] 由于目标计算机积极拒绝,无法连接。”的错误,但是b.py是没有导入DatabaseGlobal类

原因分析

Python 中的模块在被导入时会执行整个模块的代码。所以当导入一个模块时,其中的所有全局代码(在类定义之外的代码)都会被执行。即使导入的是 YamlGlobal 模块,但由于 DatabaseGlobal 类的实例化是在模块层级上进行的(不在任何函数内部),所以导入 YamlGlobal 模块时会执行 DatabaseGlobal 类的实例化代码。

这可能导致问题,因为 InstanceDaoSQLAlchemyConnect 的实例化需要数据库服务可用。如果没有数据库服务,这些实例化会导致错误。解决这个问题的一种方式是将需要数据库服务的实例化放在需要使用这些对象的函数内部,而不是在模块的顶层。

改造

原文链接:python类的初始化-CSDN博客
作者:秋不溜啾
未经许可,不得转载

将itd = InstanceDao(SQLAlchemyConnect())移动到DatabaseGlobal的__init__(self)里面

'''a.py'''
class YamlGlobal:
    with open(get_project_path() + "/cfg/global.yaml", 'r', encoding='utf-8') as f:
        glVar = yaml.load(f, Loader=yaml.SafeLoader)
    ......

class DatabaseGlobal:
    def __init__(self):
        self.itd = InstanceDao(SQLAlchemyConnect())
    ......

# 原文链接:https://blog.csdn.net/qq_33562122/article/details/135380208
# 作者:秋不溜啾
# 未经许可,不得转载

由于YamlGlobal的glVar变量也是在类的顶层,尝试不通过实例化YamlGlobal类,在b.py中通过类变量去get这个变量

'''b.py'''
from dao.get_global import YamlGlobal

if __name__ == "__main__":
    print(YamlGlobal.glVar)

不再报数据库错误,并能直接通过类变量获取glVar的结果

而现在DatabaseGlobal的itd变量,则需要实例化后才能获取,即

DatabaseGlobal().itd

小结

在类中,如果代码直接放在类下面,则视为全局代码和类变量,在第三方模块导包时,即使没有导入该类,也会执行这些全局代码,如果想推迟到类实例化再执行这些代码或者不想成为类变量而是实例变量,则需要放到__init__或类的其他函数包裹中。

  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值