直接说结论:不要用普通变量,要用"函数 / 属性 / 代理对象"来模拟全局变量。
✅ 推荐方案(从简单到优雅)
方案一:用函数替代"全局变量"(最推荐 👍)
python
def df():
return pd.read_sql("SELECT * FROM your_table", conn)
# 使用时
data = df()
👉 特点:
- 每次调用都会重新查
- 写法最清晰
- 不容易踩坑
📌 本质:把"变量"变成"动态获取"
方案二:用 @property(适合类封装)
python
class GlobalData:
@property
def df(self):
return pd.read_sql("SELECT * FROM your_table", conn)
global_data = GlobalData()
# 使用
data = global_data.df
👉 看起来像变量:
python
global_data.df # 实际每次都会执行 SQL
方案三:用懒加载对象(高级写法)
如果你真的想写成:
python
df = something
print(df) # 每次都刷新
可以用 __getattr__ 或代理对象:
python
class DynamicDF:
def __call__(self):
return pd.read_sql("SELECT * FROM your_table", conn)
def __repr__(self):
return str(self())
df = DynamicDF()
# 用法
print(df()) # 推荐
print(df) # 也会触发(因为 __repr__)
👉 但这个不太建议:
- 可读性差
- 容易误导别人以为是静态变量
❌ 不推荐方式(你可能会想到)
python
df = pd.read_sql(...)
然后试图"自动更新" → ❌ 做不到
因为 Python 变量不会自动重新执行表达式
🧠 核心理解
你想要的是:
"访问变量 → 自动执行逻辑"
但 Python 默认是:
"变量 = 已经计算好的值"
所以必须引入一层"函数 / 属性 / 动态代理"
🚀 最适合你的选择
结合你现在做的系统(数据 / CRM / 后端逻辑),我建议:
👉 用函数(方案一)
简单、清晰、团队也容易理解
如果你想写得更"像全局"一点:
👉 用 @property(方案二)
🔥 一个更工程化的版本(推荐)
python
def get_df(force_refresh=False):
return pd.read_sql("SELECT * FROM your_table", conn)
未来你可以很容易扩展成:
- 加缓存
- 加日志
- 加监控
- 加权限控制