首页 > 解决方案 > @setter:在一个方法中传递和设置所有类属性

问题描述

我需要一个可以从任何地方访问的 Singleton 类实例,它具有可以更改的某些会话变量。

class MySingletonClass(Singleton):

    @property
    def session(self):
        return self

    @session.setter
    def session(self, d):
        self.name = d['name']
        self.id = d['id']
        self.mode = d['mode']

experiment = MySingletonClass()

然后可以导入并设置变量

from core import experiment
experiment.session={'name':'my_exp_name', 'mode':'my_mode', 'id':"1234"}

我想将它们全部传递给一个函数,而不是像我目前拥有的字典那样作为函数参数。所以类似于以下内容:

experiment.set_session('my_exp_name', 'my_mode','1234')

我目前的财产方法阻止了这种情况。我确实想将每个会话变量本身作为一个属性来维护,但我也想将它们全部设置在一起,因为有很多会话变量。只是不喜欢将它作为字典传递。

如果有人可以帮助设计和/或使其更好,我将不胜感激。我需要一个类的实例,它有一堆可以从任何地方访问的变量。类中的变量可以更改,但类实例本身不能更改。我需要一个更好的方法是一次性设置所有变量(最好是一种方法而不是设置字典)

标签: pythonoopdesign-patternssingletonsession-variables

解决方案


听起来您想要一堆只读属性,但只有一个“setter”。

class MySingletonClass(Singleton):
    @property
    def session(self):
        return self

    @property
    def name(self):
        return self._name

    @property
    def mode(self):
        return self._mode

    @property
    def id(self):
        return self._id

    def set_session(self, name, mode, id):
        self._name = name
        self._mode = mode
        self._id = id

您可以使用自定义描述符减少一些样板:

class Field:
    def __get__(self, obj, type):
        if obj is None:
            return self
        return getattr(obj, self.name)

    def __set_name__(self, obj, name):
        self.name = "_" + name


class MySingletonClass(Singleton):
    name = Field()
    mode = Field()
    id = Field()

    def set_session(self, name, mode, id):
        self._name = name
        self._mode = mode
        self._id = id

推荐阅读