python 中更新实例变量的正确 OOP 方法是什么
what is the correct OOP method updating instance variables in python
我有两个 类 需要 app_config(在我的例子中 app_config 应该在我项目中的所有 类 中全局可用)。
Class1 需要 app_config,它提供了一些我需要在 app_config 中再次更新的输入,就像在 class2 中一样。
稍后我需要在 类 1 和 2 中更新 app_config。
什么是更新实例变量的正确方法。我做得对还是我需要换个角度考虑?
import requests
app_config = {
"MaxThreadCount": 10,
"BaseURL": "https://google.com",
"DB": "some db ip"
}
class Class1():
def __init__(self, app_config):
self.app_config = app_config
def get_few_more_configs_in_class1(self):
var1 = requests.get(self.app_config["BaseURL"])
print("get few data")
return {"class-1": "some inputs"}
def set_appconfig(self, app_config):
self.app_config = app_config
class Class2():
def __init__(self, app_config):
self.app_config = app_config
def gather_few_more_configs_in_class2(self, inputs_from_class1):
print("connect to db")
return {"db-inputs": "some more inpus"}
def set_appconfig(self, app_config):
self.app_config = app_config
c1 = Class1(app_config=app_config)
c2 = Class2(app_config=app_config)
class1_inputs = c1.get_few_more_configs_in_class1()
class2_inputs = c2.gather_few_more_configs_in_class2(class1_inputs)
app_config.update(class1_inputs)
app_config.update(class2_inputs)
c1.set_appconfig(app_config=app_config)
c2.set_appconfig(app_config=app_config)
这里有一些更有意义的变化:
import requests
app_config = {
"MaxThreadCount": 10,
"BaseURL": "https://google.com",
"DB": "some db ip"
}
class Class1():
def __init__(self, cfg): # you want to avoid shadowing something global
# since you have a setter, discourage direct access
self._cfg = cfg
def get_few_more_configs_in_class1(self):
var1 = requests.get(self.app_config["BaseURL"])
print("get few data")
# no need to update after return, just update directly
self._cfg.update({"class-1": "some inputs"})
# this is a better way to expose and allow setting, with a property
@property
def app_config(self):
return self._cfg
@app_config.setter
def app_config(self, cfg):
self._cfg = cfg
class Class2():
def __init__(self, cfg):
self._cfg = cfg
def gather_few_more_configs_in_class2(self):
print("connect to db")
# here, you can use whatever was previously set in your `app_config`
print("using", self._cfg['class-1'])
self._cfg.update({"db-inputs": "some more inpus"})
# this is a better way to expose and allow setting, with a property
@property
def app_config(self):
return self._cfg
@app_config.setter
def app_config(self, cfg):
self._cfg = cfg
c1 = Class1(app_config)
c2 = Class2(app_config)
c1.get_few_more_configs_in_class1()
# no need to pass stuff in, already has the config
c2.gather_few_more_configs_in_class2()
但是,既然您显然想将 app_config
用作共享应用程序 state
,或许可以这样称呼它?通常最好避免使用全局变量,因此您可以在 main()
中进行设置。最后,如果您有多个具有相同逻辑的 类,为什么不使用继承?
import requests
class StateSharing:
def __init__(self, state: dict):
self._state = state
@property
def state(self) -> dict:
return self._state
@state.setter
def state(self, state: dict):
self._state = state
class Class1(StateSharing):
def get_few_more_configs_in_class1(self):
requests.get(self.state["BaseURL"])
print("get few data")
self._state.update({"class-1": "some inputs"})
class Class2(StateSharing):
def __init__(self, state: dict, something_else: str):
super().__init__(state)
self.something_else = something_else
def gather_few_more_configs_in_class2(self):
print("connect to db")
print("using", self._state['class-1'])
self._state.update({"db-inputs": "some more inpus"})
def main():
state = {
"MaxThreadCount": 10,
"BaseURL": "https://google.com",
"DB": "some db ip"
}
c1 = Class1(state)
c2 = Class2(state, 'something!')
c1.get_few_more_configs_in_class1()
c2.gather_few_more_configs_in_class2()
if __name__ == '__main__':
main()
我有两个 类 需要 app_config(在我的例子中 app_config 应该在我项目中的所有 类 中全局可用)。
Class1 需要 app_config,它提供了一些我需要在 app_config 中再次更新的输入,就像在 class2 中一样。
稍后我需要在 类 1 和 2 中更新 app_config。
什么是更新实例变量的正确方法。我做得对还是我需要换个角度考虑?
import requests
app_config = {
"MaxThreadCount": 10,
"BaseURL": "https://google.com",
"DB": "some db ip"
}
class Class1():
def __init__(self, app_config):
self.app_config = app_config
def get_few_more_configs_in_class1(self):
var1 = requests.get(self.app_config["BaseURL"])
print("get few data")
return {"class-1": "some inputs"}
def set_appconfig(self, app_config):
self.app_config = app_config
class Class2():
def __init__(self, app_config):
self.app_config = app_config
def gather_few_more_configs_in_class2(self, inputs_from_class1):
print("connect to db")
return {"db-inputs": "some more inpus"}
def set_appconfig(self, app_config):
self.app_config = app_config
c1 = Class1(app_config=app_config)
c2 = Class2(app_config=app_config)
class1_inputs = c1.get_few_more_configs_in_class1()
class2_inputs = c2.gather_few_more_configs_in_class2(class1_inputs)
app_config.update(class1_inputs)
app_config.update(class2_inputs)
c1.set_appconfig(app_config=app_config)
c2.set_appconfig(app_config=app_config)
这里有一些更有意义的变化:
import requests
app_config = {
"MaxThreadCount": 10,
"BaseURL": "https://google.com",
"DB": "some db ip"
}
class Class1():
def __init__(self, cfg): # you want to avoid shadowing something global
# since you have a setter, discourage direct access
self._cfg = cfg
def get_few_more_configs_in_class1(self):
var1 = requests.get(self.app_config["BaseURL"])
print("get few data")
# no need to update after return, just update directly
self._cfg.update({"class-1": "some inputs"})
# this is a better way to expose and allow setting, with a property
@property
def app_config(self):
return self._cfg
@app_config.setter
def app_config(self, cfg):
self._cfg = cfg
class Class2():
def __init__(self, cfg):
self._cfg = cfg
def gather_few_more_configs_in_class2(self):
print("connect to db")
# here, you can use whatever was previously set in your `app_config`
print("using", self._cfg['class-1'])
self._cfg.update({"db-inputs": "some more inpus"})
# this is a better way to expose and allow setting, with a property
@property
def app_config(self):
return self._cfg
@app_config.setter
def app_config(self, cfg):
self._cfg = cfg
c1 = Class1(app_config)
c2 = Class2(app_config)
c1.get_few_more_configs_in_class1()
# no need to pass stuff in, already has the config
c2.gather_few_more_configs_in_class2()
但是,既然您显然想将 app_config
用作共享应用程序 state
,或许可以这样称呼它?通常最好避免使用全局变量,因此您可以在 main()
中进行设置。最后,如果您有多个具有相同逻辑的 类,为什么不使用继承?
import requests
class StateSharing:
def __init__(self, state: dict):
self._state = state
@property
def state(self) -> dict:
return self._state
@state.setter
def state(self, state: dict):
self._state = state
class Class1(StateSharing):
def get_few_more_configs_in_class1(self):
requests.get(self.state["BaseURL"])
print("get few data")
self._state.update({"class-1": "some inputs"})
class Class2(StateSharing):
def __init__(self, state: dict, something_else: str):
super().__init__(state)
self.something_else = something_else
def gather_few_more_configs_in_class2(self):
print("connect to db")
print("using", self._state['class-1'])
self._state.update({"db-inputs": "some more inpus"})
def main():
state = {
"MaxThreadCount": 10,
"BaseURL": "https://google.com",
"DB": "some db ip"
}
c1 = Class1(state)
c2 = Class2(state, 'something!')
c1.get_few_more_configs_in_class1()
c2.gather_few_more_configs_in_class2()
if __name__ == '__main__':
main()