Python同类别中方法间变量如何实现高效访问?
优化Python类内方法间变量共享的实现方式
问题背景
现有MandM类包含_ols和_sscp两个方法,当前实现是在_sscp里新建类实例调用_ols,通过返回字典获取变量——既重复创建实例浪费计算资源,又要手动解构字典,代码冗余且易出错。需求是找到更高效的方式,让类内所有方法能直接共享这些变量。
原代码核心问题
_sscp中MandM(self.data)._ols()会重新创建类实例,重复执行初始化和OLS计算,完全没必要- 依赖返回字典传递变量,每次都要手动提取,代码冗余且易出错
最优解决方案:用实例属性存储共享变量
把_ols方法计算得到的变量直接存为类的实例属性(self.xxx),这样类内所有方法都可以直接通过self访问,无需重复计算或传递字典。
优化后的完整代码
import pandas as pd import numpy as np from numpy.linalg import inv class MandM: def __init__(self, data, X_idx=2, y_idx=2): self.data = data self.X_idx = X_idx # 重命名参数避免和变量名冲突 self.y_idx = y_idx # 初始化共享属性为None,实现懒加载 self.B = None self.yhat = None self.y = None self.X = None self.resid = None def _ols(self): # 如果已经计算过,直接返回,避免重复计算 if self.B is not None: return # 用实例参数计算并赋值给实例属性 self.y = self.data.iloc[:, :self.y_idx] self.X = self.data.iloc[:, self.X_idx:] self.B = pd.DataFrame(inv(np.dot(self.X.T, self.X)) @ np.dot(self.X.T, self.y)) self.B.columns = list(self.y.columns) self.B.index = list(self.X.columns) self.yhat = self.X @ self.B def _sscp(self): # 先确保_ols已经执行,计算出共享变量 self._ols() ybar = pd.DataFrame([self.y.mean()] * self.y.shape[0]) y_ybar = self.y - ybar sscp_tot = pd.DataFrame(np.dot(y_ybar.T, y_ybar)) sscp_tot.columns = list(self.y.columns) sscp_tot.index = list(self.y.columns) yhat_ybar = self.yhat - ybar sscp_reg = pd.DataFrame(np.dot(yhat_ybar.T, yhat_ybar)) sscp_reg.columns = list(self.y.columns) sscp_reg.index = list(self.y.columns) # 直接用实例属性计算,无需从字典提取 self.resid = self.y - self.X @ self.B y_yhat = self.y - self.yhat sscp_resid = pd.DataFrame(np.dot(y_yhat.T, y_yhat)) sscp_resid.columns = list(self.y.columns) sscp_resid.index = list(self.y.columns) return {"sscp_tot": sscp_tot, "sscp_reg": sscp_reg, "resid": self.resid, "sscp_resid": sscp_resid}
优化点说明
- 避免重复计算:
_ols方法加了判断,只有当共享属性未初始化时才执行计算,多次调用_sscp也不会重复跑OLS - 变量直接访问:所有方法直接通过
self.xxx访问共享变量,无需解构字典,代码更简洁 - 参数命名优化:把原参数
X、y改成X_idx、y_idx,避免和方法内的变量名冲突,减少bug - 懒加载机制:初始化时不自动计算OLS,只有当
_sscp需要时才触发,节省初始化资源
内容的提问来源于stack exchange,提问作者GSA
相关产品推荐
相关产品推荐

